Boris
Boris

Reputation: 198

Why extend your own protocol?

I’m going over Swift 3 tutorials and documentation, and I see that there’s a design pattern that everybody are using when working with protocols. It starts by declaring a protocol with a small amount of variables (sometime just one or two) and than creating an extension to this protocol and in the extension defining some methods. For example (this is really a silly code sample, just for demonstration):

protocol Bicycle {
    var numberOfWheels: Int {get}
    var isMoving: Bool {get set}
}

extension Bicycle {
    func startPedaling() { isMoving = true }
    func stopPedaing() { isMoving = false }
}

The protocol and the extension are under my full control (since I’m the developer, and I have access to this resource file). Also, they both reside in the same resource file.

So, why are the methods reside in the extension and not inside the original protocol? For example:

protocol Bicycle {
    var numberOfWheels: Int {get}
    var isMoving: Bool {get set}

    func startPedaling() { isMoving = true }
    func stopPedaing() { isMoving = false }
}

Thanks,
 Boris.

Upvotes: 1

Views: 63

Answers (1)

Federico Ojeda
Federico Ojeda

Reputation: 768

Maybe in a case such as the one you presented, it may not make a lot of sense, but protocol extensions to your own protocols are very powerful in some cases, especially when you use the constraints into which class gets the extension.

Imagine the follwing example. I'll add to add something like a "compass"(not the best example) if the bicicle is a mountain bike. Then I would do the following:

protocol Bicycle {
    var numberOfWheels: Int {get}
    var isMoving: Bool {get set}

extension Bicycle {
    func startPedaling() { isMoving = true }
    func stopPedaing() { isMoving = false }
}

extension Bicycle where Self: MountainBike {
    var compass: Compass {get}
}

class MountainBike: Bicycle {
    //Here you can use the compass
}

class NormalBike: Bicycle {
    //Here you can't use the compass
}

Do you see? You can add specific things to each class, so the protocol can be somewhat tweaked for some class. Now every class that inherits from MountainBike can use the compass.

In this case it may be way to simple and the benefits are not that clase, but there are cases that it may be really useful, such as

protocol Controller {
    //some useful variables
}

extension Controller where Self: UIViewController {
    // Here you can use all the properties of a UIViewController
    // like getting the navigation controller, etc. Every
    // UIViewController subclass (or a UIViewController itself)
    // that conforms to it would get this methods
}

Hope it helps!

Upvotes: 3

Related Questions