我在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很新,因此我很难在模式中组织源代码。谢谢你。
答案 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
的默认实现。