Hello folks,

On this article, let's talk about the Protocol Extensions and Protocol Oriented Programming (POP). There are lots of discussions on this subject, many comparisons between Swift Protocol Extensions and Multiple Inheritance. So let's discuss the difference between both and why POP sounds much more reliable.

List of Contents



The Chicken Problem

top

I like to use this example to illustrate how complex a small problem can become into a large scale development and a real world application. Let's first see the problem and then discuss it.

Imagine an application that we need to construct "objects/entities" of birds. At first glance, we'll have Perrots, Sparrows and Falcons. Let's now create a beautiful and smart code for that.



OOP & Multiple Inheritance

top

All those birds share many things, like a "beak", "feathers" and all of them can "fly". So let's think in the following architecture for our Birds App.

Looks Great! At this point, we as developers are super proud of our creation. It's clean, reliable, we made the code once, only one implementation of the "fly" method, which is a very complex algorithm.

Now, we made the Release 1 of the product. At this point the client (owner of the Bird Application) says: "Hey, you know what, I noticed that my customers would like to have a Chicken as well, so please add Chickens to this app, it should be very easy once you told me you have a very flexible architecture working with OOP"

Ok, that's easy... Chickens are birds, so it'll become one subclass of Birds... But wait... Chickens can't fly! So at this point do I need to override this "fly()" method and just negate all my beautiful algorithm from "Bird"?

Wait, by doing this I'm not just rewriting code, however if my beloved client decides that tomorrow he'll invent a new kind of super Chicken that can fly, what am I going to do? A new sub-class of "Chicken" negating my Chicken negation to "fly()"?

And if my client decides to move the app to the South pole and create Penguins? Penguins have no feather!

OMG... I just realized that my whole Architecture is not flexible enough for my client! Should I change it? Should I rewrite my whole application? Propose a V2? Should I change my client? Should I change to another planet where Birds are perfect and they all share the same characteristics?

Ok, ok... let's calm down. Let's try to think about possible solutions, after all, OOP is great and really can reflect the complexity of the real world.

Well, not exactly. We can try to struggle ourselves with the OOP solutions. I'll not get into deep on how many fail solutions we could try:

  • Create two base classes: Bird and Flying Bird (FAIL: What if client decides to have Airplanes?)
  • Use Protocols/Interfaces to define the Flying Method (FAIL: Re-writing a lot of code)
  • Define "fly()" as a static method that receives an object that can fly (FAIL: What if I have millions of flying objects? Concurrency, multi-threading)

I've made this exercise with hundreds of different developers, letting them try many solutions. In short, the only possible solution to get out this problem in OOP is using Multiple Inheritance, however as we all know, it's hell dangerous. Only a few programming languages allow such feature and with many caveats in its own implementation. Pearl and Python use an ordered list for Multiple Inheritance, Java 8 tries to use the compiler to avoid errors, C++ is actually one of the only languages that really implements Multiple Inheritance in its full extension.

So, if you don't want to create a C++ module in your application just to solve that problem, let's try now using the Swift features solve that Chicken Problem.



Swift - Protocol Extensions

top

In short, The Chicken Problem is just a metaphor to a very common issue on software projects when two or more "objects/entities" share some common characteristics but completely differ in others. Especially in the current scenario for mobile projects, working with Agile, getting a constant feedback from the users, clients change its applications every day, which means that it can happen a lot during the maintenance of a product. So as developers, we need to construct architectures flexible enough to handle such changes.

At this point, using a good platform or programming language can help a lot to get out of those traps. At that point, Swift comes to the table with its Protocol Extensions feature. In many ways, it is compared to Multiple Inheritance, however without all the dangerous of Multiple Inheritance. Due to a single detail in this Swift feature, called Default Implementation. It means we can provide a default implementation for protocol properties and methods.


protocol MyProtocol {
    func methodOnProtocol()
}
extension MyProtocol {
    func methodOnProtocol() {
        print("Default Implementation of \(#function)")
    }
    func newMethodOnExtension() {
        print("Default Implementation of \(#function)")
    }
}

Knowing that, we can get back to the "Chicken Problem" and rewrite it, into a way that we code ONLY ONCE and still satisfying all the specific needs of Birds.

Look how flexible this can be. The Bird can still be a super class, no worries. But "fly()" and "feathers" become a Protocol with Default Implementations. Which means we CODE ONCE and we can make all kind of birds without rewriting any code.

Notice that even if our client goes crazy and says: "You know what, my Birds application know needs Airplanes, Kites and all kind of flying objects!". No worries, we built our architecture flexible enough to deal with that, because now instead of working with a single hierarchy chain in the polymorphism approach (more specifically Subtyping Polymorphism) we are now free to think as a child using Lego blocks (technically called Composition).



Protocol Oriented Programming (POP)

top

The Protocol Extension is something new, very powerful, we don't know to fully use it yet and yes, it has some caveats involved. We must practice it a lot in order to dominate this technique. It looks like Multiple Inheritance in some aspects but more sophisticated.

One of the best WWDC's video ever is the Crusty video, where Apple explain what are Protocol Extensions and Protocol Oriented Programming. I highly recommend watching this video:
https://developer.apple.com/videos/play/wwdc2015/408/

Chaing our mindset from OOP to POP requires a "leap of faith", we probably will find ourselves trying to solve problems using the OOP yet, take a deep breath, try to think as POP since the very beginning, try creating the architecture using POP before start coding.



Conclusion

top

Chickens can't fly, so the "Chicken Problem" stands for a common problem in software development, where objects/entities start sharing common features, however at some point they start diverging, becoming a completely different entity.

At this point, the traditional Polymorphism and it's single inheritance chain can't help. So at this point we need to be smart and using features such as Protocol Extensions and changing our mindset to Protocol Oriented Programming can help a lot to create a more flexible architecture and avoid refactoring whole applications just because the Client has been adding unexpected features.

That's the way the Agile world is today, we must adapt and change fast, especially in the Mobile Software Development.

Thanks for reading guys,
Please post your thoughts and comments bellow.

© db-in 2017. All Rights Reserved.