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

时间:2019-02-21 10:22:59

标签: swift design-patterns adapter

因此,我遇到了这种情况,一个已经发布的应用程序需要更改所有 API和模型


现在,我已经创建了一个通用层来处理请求和api,几乎在实现所有服务的过程中都遇到了这个问题,现在我遇到了这个问题,当然,自定义{ 1}},大型View Controller 。将每个场景中的所有内容更改为新的模型类型都会花费我太多的钱,
 因此,当我将新模型放入我的计算机中时,我想制作一个适配器来投射新模型  回调关闭到旧的类型。


我已经找到了一种方法,但是问题很长很长,我正在寻找一种更好的方法(如果存在)以及一种针对所有情况的更好的解决方案(如果存在更好的方法)。


MVC

从代码中可以看出,我创建了一个包含变量的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,现在想象一下用 +50 < / strong>变量和总共 +40 模型,可能需要一两个年龄。

2 个答案:

答案 0 :(得分: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)
    }
    ...

}

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

答案 1 :(得分:0)

因此,我使用Codable实现了这一目标,我创建了一个符合Codable的虚拟协议,并在我需要的每个classstruct中使用了该协议对其进行转换,并创建从该协议扩展的通用函数,以将该对象编码为数据,然后将其解码为所需的新类型

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

查看下面的代码。

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