使用其他类实例从类创建实例

问题描述 投票:0回答:2

所以我遇到了这个案例,一个已经发布的应用程序需要更改它的所有API和模型。


现在我已经创建了一个通用层来处理请求和apis,并且几乎在实现所有服务的中途,现在我遇到了这个问题,之前定义的模型在应用程序中广泛使用,因为它的MVC,Massive View Controller 。将每个场景中的所有内容更改为新的模型类型会花费我太多的代价, 因此,当我将它们放回到旧的类型的回调闭包中时,我想到制作一个适配器来转换新模型。


我已经找到了一种方法,但问题很长很长,我想找到一个更好的方法,如果存在更好的方法,如果有一个更好的一个更好的解决方案。


protocol Parsable {
    var time: String { get }
    var span: String { get }
    init(_ copy: Parsable)
}

class Foo: Parsable {
    required init(_ copy: Parsable) {
        self.span =  copy.span
        self.time =  copy.time
    }

    init(time: String, span: String) {
        self.time = time
        self.span = span
    }
    var time = ""
    var span = ""
}

class Fee: Parsable {
    required init(_ copy: Parsable) {
        self.span =  copy.span
        self.time = copy.time
    }
    init(time: String, span: String, date: String) {
        self.time = time
        self.span = span
        self.date = date // an extra var that is not used in Foo
    }
    var time = ""
    var span = ""
    var date = ""
}

var foo = Foo(time: "", span: "")
var fee = Fee(time: "2", span: "ye", date: "123")
// Usage
var deeped = Foo(fee)

从代码中可以看出,我创建了一个包含变量的protocol和一个包含其类型的init(),现在想象一下这个实现一个带有+50变量和+40模型的模型,可能需要一两年的时间。

swift design-patterns adapter
2个回答
0
投票

我希望我理解这个问题,这不是一个干净的解决方案,但它很快灵活:

协议中的另一个方法如何在其扩展中执行所有副本?这是可能的,因为我看到所有属性都有一个指定的虚拟值。那么实现Parsable的每个对象唯一要做的就是在初始化程序中调用这样的方法。一种commonInit()方法。

protocol Parsable {
    var time: String { get }
    var span: String { get }
    init(_ copy: Parsable)
    func initParsableProperties(from copy: Parsable)
}

extension Parsable {
    func initParsableProperties(from copy: Parsable) {
        self.span =  copy.span
        self.time = copy.time
    }
}

class Foo: Parsable {
    ...
    required init(_ copy: Parsable) {
        initParsableProperties(from: copy)
    }
    ...

}

如果需要,这还允许您在初始化程序中添加其他属性。如果您不需要其他属性,则可以直接在初始化程序中实现,但它需要一些更棘手的解决方案。


0
投票

所以我使用Codable实现了这一点,我创建了一个符合Codable的伪协议,并在每个class中使用它,我需要转换它的struct,并创建一个从该协议扩展的泛型函数,将对象编码为数据然后将其解码为所需的新类型,

有了这个,我不必声明我需要手动复制的任何变量或属性。

看看下面的代码。

protocol Convertable: Codable {}

class Foo: Convertable {
    var foo: String
    var fee: String
    init(foo: String, fee: String) {
        self.foo = foo
        self.fee = fee
    }
}
class Fee: Convertable{
    var fee: String
     init( fee: String) {
        self.fee = fee
    }
}

//Generic function to convert
extension Convertable {
    func convert<T: Codable>(_ primary: T.Type) -> T? {
        return try? JSONDecoder().decode(primary, from: try! JSONEncoder().encode(self))
    }
}
var foo = Foo(foo: "nothing", fee: "nothing")
let fee = foo.convert(Fee.self)
fee?.fee // nothing
© www.soinside.com 2019 - 2024. All rights reserved.