Reputation: 271
Assume there is a protocol Draggable
, usually will be conformed by an UIView
object
protocol Draggable {
drag()
}
We can either implement drag()
in a protocol extension as option 1
// option 1
extension Draggable where Self: UIView {
func drag() {
// implementation
}
}
extension UIView: Draggable {} // added after @Rich Tolley's answer
Or we can implement drag()
in a UIView
extension as option 2
// option 2
extension UIView: Draggable {
func drag() {
// implementation
}
}
And idea would be helpful.
Upvotes: 19
Views: 3251
Reputation: 3842
Yes, there is a difference: (EDIT: or at least there was in the original version of this q, which didn't add extension UIView : Draggable {}
to the end of option 1).
Option 1 creates a default implementation for instances of UIView
that conform to Draggable
. You still need to mark UIView
s you wish to conform to Draggable
as such in the declaration: class MyView : Draggable
. Anything that conforms to Draggable
but is not a UIView
subclass will need to supply its own implementation.
Option 2 extends all UIView
s to make them conform to Draggable
. Nothing else can be a Draggable
unless separate extensions are also written for those classes, or they are manually conformed to the protocol. There is no need to add Draggable
in the class declaration.
The protocol extension is usually the better option. In this case this is obviously true since not all UIView
s can be Draggable
. Also, going down the protocol extension route means that you can create a Draggable
object that is not a UIView
subclass, if necessary (admittedly fairly unlikely, since most Cocoa controls are UIView
subclasses - although not all -UIBarButtonItem
isn't, strangely)
If you follow option 2, you will be adding unnecessary methods to UIView
in a lot of cases, which is a violation of good object oriented design - specifically the Interface Segregation Principle (clients should not be forced to rely on methods they don't use
) - which is the 'I' in the SOLID principles
Upvotes: 9
Reputation: 12109
A protocol extension should be used when you want to implement functionality for more than just one class.
In this case you should use the extension UIView: Draggable
as the Implementation is specific to the UIView class.
Assuming you have a protocol which provides location:
protocol Location {
var location: CGPoint { get set }
}
and you want every class which implements Location to conform to Draggable, then a protocol extension could be used:
extension Draggable where Self: Location {
func drag() {
}
}
For further reference, you should have a look at Protocol-Oriented Programming in Swift from the 2015 WWDC.
Upvotes: 3