如何以模式组织 swift 源代码?

Posted

技术标签:

【中文标题】如何以模式组织 swift 源代码?【英文标题】:How to organize swift source code in pattern? 【发布时间】: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,这就是我在这里问的原因。 【参考方案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 提供默认实现。

【讨论】:

以上是关于如何以模式组织 swift 源代码?的主要内容,如果未能解决你的问题,请参考以下文章

仅在 Swift 中以横向模式打开相机和库

如何使用 Swift 以编程方式让 Mac 进入睡眠状态

更改代码块的 emacs 组织模式键绑定

如何以模块化方式组织源代码[关闭]

如何使用Alamofire Router来组织API调用?(swift Alamofire5)

如何使用 ObjectC 向下拖动以关闭模式