It feels like I’ve been digesting Apple’s WWDC 2015 talk on Protocol Oriented Programming for months now. It certainly seems like we are in the middle of a huge paradigm shift. After all, you don’t go switching orientations around willy-nilly. We’ve been doing object oriented programming for decades, so the declaration that we are moving away from it can only be seen as a rather bold one.

But although the language surrounding the new paradigm seems grandiose, the changes themselves aren’t. It’s simply the culmination of the goals Objective-C originally set out to accomplish. By emphasizing design patterns that do not require subclassing, Objective-C distinguished itself from C++ as a language that favors object composition over hierarchical class inheritance. We are not entering some new age of Protocol Oriented Programming. The new developments in Swift merely cement familiar patterns and ideas we have been embracing for almost as long as we’ve embraced OOP.

Protocol Oriented Programming is one more way of achieving a composition-based architecture. It emphasizes “has-a” relationships over “is-a” relationships. With classes, we are able to inherit functionality by virtue of an object being a kind of thing. Now with protocol extensions, an object can inherit methods and variables by virtue of having certain things.

For me, the problems of strictly hierarchical design and class inheritance became pretty clear when I was working on my random trick generating apps. I had a base class for all types of Tricks.

And then from there, I created different subclasses for each different sport. Because each sport has its own dedicated app, this felt like a natural way to draw a line between each product.

I created something like this:

etc…

But even within the different trick-based sports, there are other sub-types of trick. Skateboarding has its own set of rail tricks, snowboarding and skiing both have their own kind of jumping/aerial tricks. BMX has some combination of each as well. So you keep you subclassing to these subtypes.

The interesting thing starts to happen once you go down a few levels in the class hierarchy. That’s when parallel subclasses start to have the same properties in common with one another. For example, both SnowboardJumpTrick and SkiJumpTrick have degreesOfRotation in common (how much your body spins around while you are in the air). They also have grabs in common.

A programmer might want to add a function to both of these types, something that depends on the type having degreesOfRotation. In my case, I wanted the app to randomly generate some multiple of 180 between zero and any other multiple of 180 (540, 720, 900, etc.) because in both sports nearly all of the aerial tricks are built from combinations of half-spins.

To solve this problem, one might try an inheritance-based approach where you move degreesOfRotation to some superclass that both Snowboard Trick and Ski Trick inherit from. It might look like this.

Although adding another tier to the class hierarchy kind of solves our problem, it introduces several new ones. The jump tricks no longer need to declare degreesOfRotation, and can also inherit our random 180 spin generator function, but we’ve now shoe-horned that function onto the more generic SnowboardTrick/SkiTrick as well as anything that subclasses them. In an effort to share functionality between two classes that have the same property in common, we have created a more bloated and complicated class hierarchy that’s harder to understand.

Object composition tells us we should almost always avoid doing this when there are better options. Before protocol extensions, you could favor composition by creating a helper class that does the random 180 spin function for you and then having both Snowboard Jump Trick and Ski Jump Trick call that function whenever they need to generate a random multiple of 180. It would look like this.

You can see how this solves the problem of adding the shared functionality while also preserving a more flat class hierarchy that’s easier to understand. There’s no need for a bloated base class when we can create tiny components that each of our entities can share.

Protocol extensions extend this idea even further. Instead of making Rotatable a class, we can make it a protocol that both SnowboardJumpTrick and SkiJumpTrick adopt. Then we can extend the Rotatable protocol to add the random 180 degree spin function to anything that adopts that protocol. If we declare both SnowboardJumpTrick and SkiJumpTrick as adopting the Rotatable protocol, they both get the random 180 spin generating function.

This is really cool because it now appears as though both classes (which exist in separate hierarchies) have inherited the same method. More importantly, we’ve done it all without creating any new subclasses! The protocol extension gives us the ability to grant new functionality to two separate entities that have the same property in common. It’s “inheritance” by virtue of a “has-a” relationship as opposed to “inheritance” by virtue of an “is-a” relationship.

For all the talk, you’d think we were entering some new age of programming. Although Swift does change the game dramatically, protocol extensions are merely another way for us to build apps that favor object composition over hierarchical class organization. By giving equal weight to another kind of “inheritance,” Swift 2.0 makes official an axiom that many programmers have known for a long time; Build flexible components and subclass sparingly.