10

It seems reasonable to use UML Interfaces to visualize Swift Protocols in UML. But how should I visualize an extension that provides a default implementation for a specific protocol? Should I just use a class like <<extension>>ProtocolName that inherits from that protocol?

Christophe
  • 68,716
  • 7
  • 72
  • 138
bamboofighter
  • 299
  • 1
  • 14
  • Possibly [this Q&A](http://stackoverflow.com/questions/3686210) can be of interest for you, see specifically [@Klaim:s answer](http://stackoverflow.com/a/3686405/4573247). – dfrib May 29 '16 at 12:47

2 Answers2

8

An extension exists in the scope of a certain class and just adds some functionality to it. So I would represent the extension as subclass (eventually packaging might be preferred). To show that it's an extension I would use a stereotype. The dependency on the class which is extended is somewhat optional since in the context it is a naming convention.

enter image description here

If the extension will additionally adhere to some protocol you just add realization relations to the according interface classes.

This is one way to express this. Since there is no native UML construct for an extension you are relatively free to invent you own idiom here.

qwerty_so
  • 35,448
  • 8
  • 62
  • 86
  • Interesting. I have the impression that this could apply for class extensions. But protocol extensions extend the protocol for all the conformant classes. This means that these suddenly inherit features that they do not realize themselves, i.e. like an abstract class more like than an interface, isn't it? – Christophe Jan 16 '22 at 14:13
  • @Christophe Well, I more or less gave up on Swift since its military doctrine on type checking works like Catch 22. The above was something I came up with quite some time ago. There might be better ways, but I'm not so keen to explore it in more depth. – qwerty_so Jan 17 '22 at 09:53
  • 1
    Oh, I think your answer helped a lot of people and is certainly a valid approach for classes. On my side, I continue to explore this interesting language, although these interfaces which are much more than interfaces once they get extended, somewhat blurry the lines (not even to speak about the enums that behave like classes with variable attributes) ;-) – Christophe Jan 17 '22 at 10:56
0

In short

A Swift protocol is in principle an UML interface: a class does not inherit anything from an interface/protocol, but must implement the feature that the interface/protocol promises.

Protocol extensions change this semantic equivalence: a protocol extension can provide features that the conformant classes would inherit. This is incompatible with an UML interface and corresponds to the semantic of an abstract class. But using abstract classes would make it confusing in regard to multiple inheritance. A stereotype «protocol» would seem preferable.

More explanations

Protocols

A swift protocol that is not extended corresponds indeed to an UML interface, despite slight differences in the wording:

Swift: A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.

vs:

UML: An Interface is a kind of Classifier that represents a declaration of a set of public Features and obligations that together constitute a coherent service. An Interface specifies a contract; any instance of a Classifier that realizes the Interface shall fulfill that contract.

Class extensions

There are different kind of extensions. A class extension adds features to the classes that they extend. If the extension occurs in the same file, it even has access to the private members of the class.

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()

The extension does not have a distinct name: it just redefines the original type, and the class behaves as if the initial definition and extensions would be the same classifier, just split up in the source code:

  • If the extensions and the initial class are defined in the same package, the cleanest way to represent it in UML would be to enrich the initial class, in the UML diagram.
  • If the extensions are defined in another package you could represent the full set of extensions to the same class as an own class, and a merge package to combine both. Since the original class is required for the extension to work you could in addition show a dependency between the two. Alternatively you could also think of an «class extension» stereotype. But again, grouping all the extensions to the same class in the package, because of the UML unique naming constraint.

Protocol extensions

Protocol extensions change the nature of the underlying protocol. While the original protocol was an interface without any implementation, the extended protocol will provide some implementations:

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);

In UML, the extended protocol would correspond to an «abstract» class, i.e a class that cannot be directly instantiated because of some missing features, but which may have some features well defined that are inherited. This situation is not fully supported in UML, since there is no modelling way to transform an interface into an abstract class:

The cleanest way would then be to use an UML profile that defines the stereotype «protocol» as a special form of «abstract» classes. The protocol extensions would then be dealt with as explained above for the classes, using a «protocol extension» in the situation where a «class extension» was mentioned.

Christophe
  • 68,716
  • 7
  • 72
  • 138