Showing posts with label protocol oriented programming. Show all posts
Showing posts with label protocol oriented programming. Show all posts

Saturday, December 10, 2016

Swift 3, Protocol-Oriented Programming

My new book, Swift 3 Protocol Oriented Programming has been released.  I wrote the original Protocol Oriented Programming book when Swift 2 was released and since then a lot has changed with the language.  This new book is a major rewrite and includes an additional chapter on generics.  The following gives an overview of each chapter:

Chapter 1, Object-Oriented Programming vs Protocol-Oriented Programming, This chapter will show the differences between object-oriented programming and protocol-oriented programming giving the reader a good understanding of the difference paradigms.  By the end of the chapter the reader should have a basic understanding of protocol-oriented programming and what it offers.

Chapter 2, Our Type Choices, In this chapter we will look at the different types that Swift offers (Structs, Classes, Enums and Tuples).  We will show several examples of when to use the various types and when not too.

Chapter 3, Catching our Errors, This chapter will look at the various ways that we can catch and report errors.  This chapter will not only cover the new Swift 2 do-try-catch blocks but also the older error catching patterns

Chapter 4, It’s all about the Protocol, This chapter will be all about the protocol.  We will show the advantages of using protocols and why, in our design, we should always think about the protocol first and the actual types that conform to the protocol second.

Chapter 5, Lets extend some types, This chapter will cover extensions in great detail.  We will look at how to extend standard Swift types like structures and classes.  We will also look at protocol extensions and discuss why they are so important to Protocol-Oriented programming.

Chapter 6, Working with Generics, This chapter will cover generics.  We will look at how we generics can be used with the protocol-oriented programming paradigm to write flexible and reusable code.

Chapter 7, Design Patterns with Protocol-Oriented programming, We will be implementing several design patterns using protocol-oriented programming.  For each of the design patterns we will look at the problem they are designed to solve and how to implement the pattern.

Chapter 8, Case Studies, In this chapter we will explore three case studies.  This chapter is designed to pull everything from the first six chapters together to show the reader how to use Protocol-Oriented programming is real world situations.


This book will guide you through every aspect of protocol-oriented programming to help you take advantage of it in your applications.  You can purchase a copy of the book on Amazon.

Sunday, April 17, 2016

What is Protocol Oriented Programming to me?

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.



Sunday, March 20, 2016

Generic Programming and POP with Swift – The Law of Useful Return

In my first post on Generic Programming I talked about the iterative approach to improving algorithms.  In this post I would like to discuss another concept from the From Mathematics to Generic Programming book that I am currently reading. This concept is called The Law of Useful Return.

The Law of Useful Return says:

If you have already done the work to get some useful result, don’t throw it away.  Return it to the caller because they may be able to use it.

What do we mean by this law.  Well the easy way to explain it is to look at an example.  In the From Mathematics to Generic Programming book, they explain this law based on a mathematical equation however, most developers that I know do not get that excited about complex mathematical equations therefore I am going to take a non-mathematical approach to explaining this.

Lets say that we were creating a pump that is connected to the Internet for real time monitoring (think IoT).  This pump could be used to pump different types of liquids and would be able to return the temperature of the liquid as it is being pumped.  In our application, that monitors the pump, we could then retrieve the temperature and send out an alert if it is outside of the acceptable range for the particular liquid that is being pumped.  Our function to monitor the temperature may look something like this:

func isTemperatureWithinRange() -> Bool {
    //Get liquid temperature
    var temp = getLiquidTemp()
   
    //Check if temp is within acceptable range
    if temp < MIN_TEMP || tem > MAX_TEMP {
        return false
    }
    return true
}

This function would work well and if the temperature was outside the acceptable range it would return false triggering an alert.  The problem that could arise from this is eventually we will want to display the actual temperature of the liquid being pumped, therefore someone may add another function that would simply retrieve the temperature of the liquid and return it.  This function may look something like this:

func getTemperature() -> Double {
    //Get liquid temperature
    return getLiquidTemp()
     }

Now in order to retrieve the temperature of the liquid and to also check if it is within the acceptable range we would need to call the getLiquidTemp() function twice.  Since this function retrieves the temperature from a remote device, making two separate calls like this is definitely not optimal.  What we could have done to avoid this problem was to return the temperature with the Boolean value that indicates if the temperature was within the acceptable range.  It would be very easy to do since we are already retrieving the temperature as part of the check.  The function that returns both values could look something like this:

func getTemperature() -> (acceptable:Bool, temperature: Double) {
    //Get liquid temperature
    var temp = getLiquidTemp()
   
    //Check if temp is within acceptable range
    if temp < MIN_TEMP || tem > MAX_TEMP {
        return (acceptable:false, temperature: temp)
    }
    return (acceptable:true, temperature: temp)
}

Be careful not to follow this law to closely because we only want to return data that is useful within our application.  When we create functions like this we really need to ask ourselves not only what information do we currently need but also what information may be useful.  In our example above, returning the temperature, since we already retrieved it, could definitely prove useful even if it is not needed with our current requirements.  Writing our API correctly (generically) the first time will save us from having to change the interface for our APIs in the future.  This means a lot less refactoring of our code.

To me, one of the ideas behind the Law of Useful Return is to avoid making our APIs so granular that we end up performing the same functions multiple times.  To illustrate this idea another way lets look at a second example.  Lets say that we have a NSDate object and we need to retrieve the month from it.  We could very easily design our API like this:

func getMonth(date: NSDate) -> Int {
    let components = NSCalendar.currentCalendar().components(.Month, fromDate: date)
    return components.month
}

This works great for our present need however what happens if in the future we also need to retrieve the day of the month.  We could write a second function to retrieve the day of the month however we would then need to make two function calls if we needed both the day of the month and month itself.  A better way to design our API is to think ahead and realize that if we are retrieving the month from the NSDate object maybe the day of the month and year would be useful.  We would then create a function that returns the month, day and year like this:

func getDate(date: NSDate) -> (month: Int, day: Int, year: Int) {
    let components = NSCalendar.currentCalendar().components([NSCalendarUnit.Month, NSCalendarUnit.Day, NSCalendarUnit.Year], fromDate: date)
    return (month: components.month, day: components.day, year: components.year)
}

By designing our API to return the month, day and year rather than just the month our function becomes much more generic and useful not just for our present needs but also for our future needs.

When we create APIs that only meet our present requirements we end up having to do a lot of extra code refactoring in the future when we have to change those API to meet our future needs.  When we are designing our APIs we should always remember to think beyond our present needs and think about how we can make our APIs generic enough to also meet our future needs.

There are going to (hopefully) be a number of posts in the Generic Programming and POP with Swift series therefore I made a separate post that contains links to all of the articles in this series.  The post is located here:  http://masteringswift.blogspot.com/2016/03/generic-programming-and-protocol.html