I have had numerous conversations about what exactly is
Protocol Oriented Programming since my Protocol Oriented Programming with Swift book was released.
Everyone I spoke to seemed to have his or her own opinion about what POP
is. Out of all of those conversations I
think this is the best explanation that I heard “Programming with an
orientation toward the use of protocols for abstraction”.
So what do we mean when we say that POP is “Programming with
an orientation toward the use of protocols for abstraction”? Quite simply my interpretation of this is
with POP we should be programming to a protocol and not to an
implementation. This is very similar to
other languages where we use interfaces however Protocols in Swift take a more
predominate role within the language itself where as other languages, like C#
and Java, the interface really takes a back seat to the class hierarchy.
In my POP vs OOP post I demonstrated a lot more than just the protocol so you may be asking yourself
what are all of the other features that I talked about. This is very similar to saying that Object
Oriented programing is based on the concept of programming with objects. Now we all know that good OOP design is about
a lot more than just the object, similarly good POP design is about more than
just the protocol which is why I think Apple introduced Protocol Extensions
during their POP presentation (I could be wrong about and it is just my
opinion).
So what makes for a good POP design? The post that I wrote that compared OOP to
POP really showed what I think is good
POP design. You could also pick up my Protocol OrientedProgramming with Swift book on the subject as well
:). In this post rather than going in
depth in to POP design I would like to touch on a couple of points that people
have brought up to me based on my book and earlier post.
Protocol Extensions are simply syntactic sugar
When people say that Protocol extensions are simply
syntactic sugar they are absolutely correct however there is nothing wrong with
syntactic sugar. There are other ways
that we can avoid duplicate code when using value types however protocol
extensions are very convenient and also gives us good code organization however
for good code organization we do want to avoid having multiple extensions for a
single protocol or type. For example we
should avoid this unless each extension has different constraints defined.
protocol Foo {
var x: Int {get set}
}
extension Foo {
func add(y: Int) -> Int {
return x + y
}
}
extension Foo {
func sub(y: Int) -> Int {
return x - y
}
}
Use Protocol Extensions with caution and use
constraints where necessary
It is very ease to simply add a protocol extension without
thinking too much about the types that conform to the protocol. For example in my POP book I used the
following example of how to extend the CollectionType
protocol. I then followed it up in my book up by pointing out how this
extension does not work for all types that conform to the CollectionType
protocol like the Dictionary
type therefore we either needed to use a constraint to limit the implementations that received this functionality or only extend the specific
implementation that needs this functionality..
extension CollectionType {
func
evenElements() -> [Generator.Element] {
var index = self.startIndex
var result:
[Generator.Element] = []
var i = 0
repeat {
if i % 2 == 0 {
result.append(self[index])
}
index = index.successor()
i += 1
} while (index != self.endIndex)
return result
}
func shuffle()
-> [Self.Generator.Element] {
return sort(){ left,
right in
return arc4random() < arc4random()
}
}
}
Avoid getting to granular with your protocols
To me, making smaller more specific protocols and using
protocol inheritance and composition as I illustrated in my POP vs OOP post is an advantage that POP design has over OOP design however it was pointed out
to me by a very smart person that we need to avoid getting to granular with our
protocol designs. In OOP we have the
problem where we get large monolithic super classes and sometimes this can not
be avoided however with POP we as programmers and architects need to avoid
making our protocols to granular. The
following code illustrates what we want to avoid.
protocol FooAdd {
func add(x: Int, y: Int) -> Int
}
protocol FooSub {
func sub(x: Int, y: Int) -> Int
}
protocol FooMul {
func mul(x:Int, y: Int) -> Int
}
struct Bar1: FooAdd, FooSub, FooMul {
func add(x: Int, y: Int) -> Int {
return x + y
}
func sub(x: Int, y: Int) -> Int {
return x - y
}
func mul(x:Int, y: Int) -> Int {
return x * y
}
}
In this example, FooAdd, FooSub and FooMul protocols only
contain one function each and those functions are related (mathematical
operation) therefore it really makes since to put them into a single
protocol. If you have multiple protocols
that you are always grouping together, you may want to consider combining them
into a single protocol.
Error Handling in POP
In my Protocol Oriented programming with Swift book, I have
a chapter on error handling. I have been
questioned about this since error handling is really part of the language
itself and not really part of the POP paradigm.
These people are absolutely 100% correct however anytime we write or
design an application we need to worry about how we will respond to and recover
from errors therefore to me error-handling needs to be a part of any good
design. With this in mind, in my
opinion, a book that talks about design, with a specific language, should include
something on error handling. That really
is just my opinion and hopefully explains why I included a chapter on error
handling in my book.
My Books and Posts
I received a one star review of my Protocol Oriented
Programming with Swift book with a comment about my writing style. Another person responded to the comment
saying “The writing style in this
book is actually very good. It is written so even the non-programmer can
understand and grasp the concepts behind POP.” That is really my goal not only in my books
but also in this blog. I try to write in
a way that everyone can grasp the concepts discussed. My favorite review that I have received for
any of my books was one for my Mastering Swift 2 book where the reviewer said,
“This book is simple
enough my 13 years old has started reading it and while I do not anticipate him
reading past chapter 12...it is easy enough for him to follow.” I hope that I will always continue that
writing style.
You see to me programming is something that is fun and
magical. I still remember the feeling I
had as a 13 year old kid and writing my first Brickout game on a Commodore
VIC-20. Programming does not need to be
overly complicated however we do need to ensure that our code works properly
and can be easily maintained. I really
hope my posts and my books have helped.