如何在模式中组织swift源代码?

时间:2016-07-23 11:17:20

标签: ios swift3

我在java中有一些组织良好的代码,因此它可以帮助我管理源代码以及将来轻松扩展。这些代码如下

public interface IDataModel<T extends IDataModel> {
    void copyData(T data);
    long getUpdatedTime();
}


public abstract class AbstractDataModel<T extends IDataModel> implements IDataModel<T>{
  protected long updatedTime;

  public long getUpdatedTime(){
    return updatedTime;
  }
}

public class concreteDataA extends AbstractDataModel<concreteDataA>{
  String property1;

  public String getProperty1(){
    return property1;
  }

  @override
  public void copyData(concreteDataA data){
    property1 = data.getProperty1();
    updatedTime = data.getUpdatedTime();
  }
}

现在我想进入iOS swift 3.0。可以像上面那样在swift 3.0中组织代码吗?或者在swift中有任何等效的方式来组织上面的代码?我对swift iOS很新,因此我很难在模式中组织源代码。谢谢你。

1 个答案:

答案 0 :(得分:2)

你没有提供太多的上下文,但似乎你正在努力开发一个“面向协议”的解决方案,因为Swift人喜欢称之为模式。以下是一些可能解决您问题的选项(剧透 - 我认为问题出在您的设计中):

接口:协议,抽象类:协议扩展

就像@sulthan提到的那样,你当然可以使用默认实现的协议到达类似的地方,如下所示:

protocol DataModel {
    mutating func copy(data: Self)
    var updatedTime : Float { get }
}

extension DataModel {
    var updatedTime : Float { return 0 }
}

但是,当您尝试实现ConcreteDataModel时,您将遇到问题,因为您希望将其专门化以解决协议中未提及的property1值。您可以选择放宽ConcreteDataModel中的要求(也就是不要这样做)或使用类型转换。 请注意,与Swift中的打字系统作斗争是一个明确的信号,表明您的代码不是惯用的!你应该把这种困难视为推动你重新考虑你的方法的语言。

使用不可变数据类型

这是最直接的答案。如果您上面描述的内容实际上是您的应用程序的具体示例,那么您根本不需要协议。 (事实上​​,你的Java实现肯定是过度抽象的。)Swift struct是不可变的,这意味着每当你更改它们时,你实际上是在改变副本。

struct DataModel {
    let updatedTime: Float

    mutating func update(time: Float) {
        self = DataModel(updatedTime: time)
    }
}

var data1 = DataModel(updatedTime: 3)
var data2 = data1
data2.update(time: 17)
print(data1.updatedTime)  // 3.0
print(data2.updatedTime)  // 17.0

根据您的数据建模您的行为

这是一般化的解决方案。从设计的角度来看,很明显你有两个不同的问题。你想要一些可复制的东西,你想要一些跟踪“时间”的东西。为什么不让你的代码反映出来?

protocol Copier {
    associatedtype Data
    func copy(from: Data) -> Data
}

protocol Clock {
    var time: Float { get }
}

class AlarmClock: Clock, Copier {
    let time: Float
    let alarm: Float

    init(time: Float, alarm: Float) {
        self.time = time
        self.alarm = alarm
    }

    func copy(from: AlarmClock) -> AlarmClock {
        return AlarmClock(time: from.time, alarm: from.alarm)
    }
}

当然,如果你真的需要,你甚至可以走到最后一步并提供Clock.time的默认实现。