使用UML接口来可视化Swift协议似乎是合理的。但是,我应该如何可视化提供特定协议默认实现的扩展呢?我是否应该使用类似于<<extension>>ProtocolName
的类来继承该协议?
使用UML接口来可视化Swift协议似乎是合理的。但是,我应该如何可视化提供特定协议默认实现的扩展呢?我是否应该使用类似于<<extension>>ProtocolName
的类来继承该协议?
Swift 协议原则上是 UML 接口:类并不从接口/协议继承任何东西,但必须实现接口/协议所承诺的功能。
协议扩展改变了这种语义等价性:协议扩展可以提供符合类将会继承的特征。这与 UML 接口不兼容,对应于抽象类的语义。但使用抽象类的话,在多重继承方面会令人困惑。「协议」类型标记似乎更可取。
Swift 协议如果没有被扩展,实际上对应于 UML 接口,尽管措辞上有细微差别:
Swift: 协议定义了适用于特定任务或功能块的方法、属性和其他要求的蓝图。然后,该协议可以由类、结构体或枚举采用,以提供这些要求的实际实现。
相比之下:
UML:接口是一种分类器,它表示一组公共特征和义务的声明,这些特征和义务共同构成了一个连贯的服务。接口指定了一个合同;实现接口的任何分类器实例都应该履行该合同。
有不同类型的扩展。类扩展为它们所扩展的类添加功能。如果扩展发生在同一文件中,它甚至可以访问类的私有成员。
class MyClass {
func hello()->Void { print ("Hello, World !"); }
}
var c = MyClass()
extension MyClass { // first extension
func hellobye() -> Void { hello(); print(" Good bye!"); }
}
extension MyClass { // second extension
func bye() -> Void { print("Au revoir!"); }
}
c.hello() // the object has all the features of class + extension
c.hellobye() // even if it was defined befor the extension
c.bye()
该扩展没有明确的名称:它只是重新定义了原始类型,类的行为就像初始定义和扩展是相同的分类器,只是在源代码中分开:
协议扩展改变了底层协议的性质。虽然原始协议是一个没有任何实现的接口,但扩展协议将提供一些实现:
protocol MyProto {
var v1:String { get }
func op1() -> Void
func op2() -> Void
}
class Test : MyProto {
var v1:String = "abc"
func op1() -> Void { print("Op 1"); }
func op2() -> Void { print("Op 2"); }
}
extension MyProto {
var dev1:String { get { return "de"+v1; }}
func combo() -> Void { op1(); op2(); print("Combo 1 and 2"); }
}
var test = Test()
test.combo()
print (test.dev1);
«abstract»
类,即一个由于某些缺失特性而无法直接实例化的类,但可能具有一些明确定义的继承特性。由于没有建模方式将接口转换为抽象类,因此UML并不完全支持这种情况。«protocol»
原型的UML配置文件,作为«abstract»
类的一种特殊形式。然后,协议扩展将像上面解释的类一样处理,使用«protocol extension»
来处理«class extension»
的情况。