【问题标题】:How to organize swift source code in pattern?如何以模式组织 swift 源代码?
【发布时间】:2016-07-23 11:17:19
【问题描述】:

我有一些组织良好的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 iOS 很陌生,所以我很难按模式组织源代码。谢谢你。

【问题讨论】:

  • 是的,这是可能的,但总的来说 Swift 比 Java 有更好的代码组织方式,主要是因为扩展和使用协议的更好抽象。您不能创建抽象类,但可以为协议方法添加默认实现。
  • “组织”是什么意思,缩进? control + i, 在 Xcode 中会正确缩进你的代码。
  • 谢谢@Sulthan,你能给我一个与上面等效的swift代码示例吗?
  • @MichaelP 不,先尝试一下。另外,您的示例不完整。
  • @Sulthan 好的,谢谢。但是我当然尝试过自己,但似乎我没有很好地掌握 Swift,这就是我在这里问的原因。

标签: ios swift3


【解决方案1】:

您没有提供太多的上下文,但您似乎正在努力开发“面向协议”的解决方案,因为 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 structs 是不可变的,这意味着无论何时更改它们,实际上都是在更改副本。

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 提供默认实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-29
    • 2010-10-08
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    相关资源
    最近更新 更多