Saturday, 25 February 2017

Is Protocol Oriented Programming A Game Changer?

Hello,

Its been quite a while, I haven't  bombarded the blogspot with my thoughts!! Better late then never, So I am back with a another topic. Topic for todays discussion is "Is Protocol Oriented Programming A Game Changer? Or Just Another Fancy Concept in Ever Changing Programming World".

                          Yeah!! I know, not a very interesting title isn't it, but then am not an author either, am I??  :) Protocol Oriented Programming, a fancy term tossed by apple with the release of its brand new programming language called "SWIFT".

                           In this post I'll try analyzing what Protocol Oriented Programming brings to the table, Pros and Cons of Protocol Oriented Programming that I found in my experience with swift for past one year, and Finally will try analyzing the credibility of Apple's statement "Almost everything that you can achieve with Inheritance can be achieved with protocol as well. Protocols are the alternative of Inheritance."

                          This isn't something new, I have already posted a question in stack overflow and it hasn't been answered since September 2016, if you have a thought, feel free to post it in SO. So let's get started.

                         Though the word  Protocol Oriented Programming revolves around Swift, protocols are not something new in programming world. All traditional Object Oriented Programming languages that I am aware of had it, just that they called it with different names. One such programming language is Java and it called the same concept by name "Interface".

Enough is enough, will you spill the beans,  
What on earth is Protocol Oriented Programming ????

Like in Object Oriented Programming objects are the center of attraction, In  Protocol Oriented Programming protocols/interfaces takes all the lime light. In OOP we try to model the real world scenarios/entities as objects in the memory by binding properties and behaviors to each of these objects where as Protocol Oriented Programming suggests you to conceptualize each capability as a protocol.In Protocol Oriented Programming you try model the entity as a structure and not as a class and will continue to stick with structures until and unless converting it to class is absolutely essential. You declare each capability shared among multiple entities as a protocol rather than declaring it as a method in base class. This allows each entity to opt specifically the capability they are interested in and also prevents you from falling into the pit of Multiple Inheritance.

Why do we even need Protocol Oriented Programming!!
Whats wrong with traditional Object Oriented Programming ???

 OOP provided a perfect solution to model real world use cases, as one could bind data and behavior in a single entity called Objects, OOP  provided an awesome and powerful mechanism to do data and functional abstraction. Looked like developers had finally found the missing link to develop robust real world applications which could never have been possible with plain old Functional Languages. 

The four most important fundamental concept of any OOP language are
1. Encapsulation
2. Abstraction
3. Polymorphism
4. Inheritance.

The one that is of prime importance for us today is Inheritance. Probably one of the most celebrated aspect of OOP was Inheritance to be frank even today it is! Though Inheritance is loved and extensively used by developers, careless use of Inheritance often leads you to scenarios, recovering from which might need you to remodel the whole program/project. Yes am talking about Multiple Inheritance and Diamond Problem.

As we are aware OOP language like JAVA, Objective C does not support Multiple Inheritance, ever wondered why ?? Because of Diamond Problem.

Diamond Problem :
For a time being lets assume Java/ Objective C supports Multiple Inheritance.
Code in Java : Code in Objective C :
Class C extends both class A and class B, and unfortunately both class A and class B provides the method with same signature printName() and class C decides not to override printName() then on calling this.printName() on C's instance, compiler will be confused as which implementation of printName() to invoke ? Class A's implementation or that of Class B's.

Few OOP languages like C++ solves Diamond problem in their own way there by continues to support multiple inheritance, but languages like Java and Objective C does not have any implemented rules to deal with Diamond Problem, hence does not support Multiple Inheritance.

Fine! If my programming language does not support Multiple Inheritance, I don't need it either!! Big Deal, huh!! Hold your horses friend, thats a trap!! and you know who laid that out for you ? Your beloved Inheritance!!!

How come Inheritance will lead me to the trap of Multiple Inheritance ?? You think am nuts to believe that !!

Lets build a hypothetical game of super heroes savvy??? Requirement though is that you must have seen Avengers, at least one of its part or at least be familiar with the characters of Civil War. Those who dont know what am talking about, "Go Watch Pogo!!"

 Lets start with picking up the characters for our game. Hmmmm, lets start with ma favorite Iron Man(Tony Stark), War machine (Rhodes), Natasha (Black Widow), Barton and finally Hulk (Dr. Banner). Looks like I have a quite a strong army of my super heroes!!! Whats common in them? Ohhh, I got it they are all humans. Lets go and create a base class named Humans.

Code in Java : Code in Objective C : this looks fine, all the common functionalities of humans are gathered together in Humans base class. Now all my super heroes can extend from Human base class and add additional capabilities of their own.

Hang on second, both Iron Man and War machine can fly. Why shouldn't I add flying capability to common class lets say FlyableHumans and make Iron Man and War Machine extend from it??
Code in Java : Code in Objective C : Wait a second, I forgot to add Thor and Loki (The asgardian gods) to the game. Whats common in them they are aliens :) Lets create a base class called Aliens.

Code in Java : Code in Objective C : But now Thor can fly just like Iron Man or War machine and we have implemented fly() capability in FlyableHumans. I don't want to re-implement fly to Thor, but then I can't extend from FlyableHumans either can I ?? After all he is a god(Alien) and not a human :p

Code in Java : Code in Objective C : Now complier shows error message!!! You can't extend multiple classes! 

How did I even ended up in such scenario, because I declared fly as a behavior in FlyableHumans class and now I can't extend multiple classes :( You Inheritance, you tricked me into this :'(

Dont worry my friend, here comes the hero, Protocol Oriented Programming to save us!

Solution in Protocol Oriented Programming :

Now lets try conceptualize this from a Protocol Oriented Programming perspective! We ended up in trouble because we added the fly capability as a behavior of Flyable Humans class, rather if flying was a independent capability (protocol) then, all super heroes who are interested in flying could have opted for it individually. Because classes can implement/confirm to multiple interfaces/protocols we can use interfaces/protocols as a work around to overcome the inherent shortcoming of native language not supporting multiple inheritance.

Code in Java :
Code in Swift :

Now both Iron Man and Thor can happily fly while being Human and Alien respectively :P

Thats it, So Protocol Oriented Programming solves multiple inheritance problem by declaring capability as protocol.
Does that mean Protocol Oriented Programming is better compared to Object Oriented Programming ? Does Protocols replaces traditional Inheritance as apple claims ??

I dont think so!!
One of the biggest advantage of Inheritance was code reusability. How can we even deny the comfort we all took by writing common functionality once in parent class and getting it free in all child classes!

Or How can we even forget, how easily we tweaked the parent class's method implementation just by overriding parents method and adding only the specialized code in Childs implementation while still getting the benefit of parent class method implementation just by calling super.methodName().

Finally, how can we ignore the fact, how easy it was for us to provide completely different implementation for child just by overriding parent class method and by not calling super.methodName().

One of the biggest disadvantage with Protocol Oriented Programming approach with languages like JAVA is that each class that decides to confirm/implement a protocol/interface, must provide its own implementation of the method. Now this makes code reusability nil.

As we can see in the above code snippet, though IronMan, WarMachine and Thor all implement the same FlyingCapability interface they have to provide their own implementation of fly() method. That makes the code maintenance a nightmare!!

Now Swift seems to have thought about it a bit. In case of swift, protocols can provide their default implementations to their methods. Classes which does not require any special implementation other than the default one need not provide any implementation of their own !!!

As you can see, though IronMan, WarMachine and Thor confirm to FlyingCapability they do not provide any implementation of their own. Thats a good news!! Some code reusability finally!!!

But then, Thor Doesn't fly like Iron Man or War Machine does he ??? He has to throw his hammer in the direction he wants to fly to fly with it!!! So I need the fly functionality but with a little tweak!!! Should be very easy, I have fly capability already implemented I just need to add some special line of code for Thor and then call super.fly() Isn't it ??? Nope.

As you can see, if Thor decides to provide his own implementation of fly, he wont get any help from default protocol extension implementation. He has to provide his own completely!  Swift protocols comes with default implementation which you can either as is form else simply discard and provide a complete brand new implementation!!! But in real life how frequently we use the default implementation without a tweak ??? Almost close to nil!! So there goes our code reusability my friend :(

Surely Apple has thought about protocols and code reusability compared to JAVA (after all Swift is a Protocol Oriented Programming Language) but not enough to retain all the benefits of inheritance!!!

Swift Protocol am disappointed with you!!! :D

So if inheritance was so nice! why did we try replacing it with protocols/interfaces in very first place ? Is there no way to over come multiple inheritance while still sticking with inheritance all the way ?

Isn't there a work around to Multiple Inheritance while not opting for Interfaces/Protocols and continue working with inheritance ??

In my view, there is. I wont say it is a perfect work around to  Multiple Inheritance but then we don't have any perfect work around either do we ??

Component Oriented Programming :
Rather than declaring the capability as a method in class (like in Object Oriented Programming) or as a protocol/interface (like in Protocol Oriented Programming) if we could declare it as a reusable component and then make this component available to all the classes which wants to opt it, we can still circumvent  the issue of Multiple Inheritance and yet continue to get all the benefit of code reusability!!!

Code in Java :
Code in Swift :

Lets tackle Thor's flying problem, shall we ???

Code in Java :
Code in Swift :
Now when Thor wants to tweak the default implementation of flying capability a bit all he has to do is to create a private class extending the FlyingCapability component override its fly() method, add his custom hammer throwing code and then simply call super.fly(); Code reusability ensured!

Cons :
As perfectly pointed out by my Technical Architect Giju Eldhose, the biggest disadvantage of Component Oriented Programming are

1. Because components are added as property to a class, added capabilities no longer confirm IS-A relationship but follows a HAS-A relationship.

2. Capability can no longer be called directly on object, but has to follow dot format to access the capability declaring property and then call the capability itself.
like : self.flyingCapability.fly()
not like : self.fly();

As per apple Component Oriented Programming makes code clumsy, but then expecting a clean code with Protocol Oriented Programming  which supports No/less Code reusability isn't great idea either I believe.

I agree with Component Oriented Programming we are messing up the code readability (with all those . formats) but then if we stack up the odds, I still feel Component Oriented Programming does a fair job with code reusability than apple's suggested Protocol Oriented Programming.

Conclusion :
I usually conclude all my blog posts with some pre made up conclusion like few reporters of  National News Channel in India after their detail unbiased debates :p , but this time Am gonna keep it open!

I have explained my analysis in detail in this article. Now its up to you to decide what flavor of Programming you gonna use to circumvent multiple inheritance, Apple suggested Protocol Oriented Programming or Component Oriented Programming :)

Leave your thoughts below :) I'll be glad to hear your thoughts :D