I have to admit that, for me, it was one of those moments when a lot of the things finally click together: some of the intuitions I’ve had in the last years, the certainty that there had to be a better way, but not knowing exactly how to find it, the feeling that the Java/.Net approach to OOP leaves much to be desired, and in particular, the conviction that often times we look at the wrong abstractions, and we must abstract behaviour, and not entities.

Obviously, a session like that would not have been possible a year ago. Some of the new features introduced with Swift 2, in particular protocol extensions, make that shift in paradigm possible.

And that, to me, is precisely what is important here. Apple continues to tell us developers to think out of the box, to Think Different (that very last slide in the presentation gave me the goosebumps). Yes, we are different, we have always been different.

We are creative, resolutive, reckless, relentless people, that love thinking out of the box, and find solutions to conventional problems in an unconventional way.

I was about start writing the mandatory “What’s new in Swift 2” post, when I decided that yet another post about try and proper Generic support in enumerations was not precisely what the world needed.

So, since TDD is so near and dear to my heart, here is an overview of what’s new on Xcode 7 (as of beta 1), when it comes to unit testing.

UI Testing, made easy!

Finally, there is a way to test user interfaces. Well, actually, there has been one for a long time (UIAutomation), so let me rephrase: finally, there is a simple and well integrated way to test user interfaces.

By this time, I guess everyone has seen a demo, or the relevant WWDC session recording, but it is as easy as clicking a button, start interaction with the UI, and then add an assertion.

By the way, no offence, but it is just the demo mindset, but Apple’s testing samples usually include more than one assertion by test. Not cool. Tests should fail for a single reason.

Anyway, the cool thing is not only how easy it is to test UIs, but that a UI testing target is added to new projects by default.

Test all the things! No not add all the things to the testing bundle!

There is no need to add production code to the testing bundle anymore. If you recall, until now, if you wanted to test a particular Swift class, you needed to add it to the unit tests bundle as well. Not cool.

Now, all you need to do is import the module under test using the @testable keyword. That is cool, because, again, you do not need to add your production source to the testing bundle, which is ugly and dirty, but is also a little bit meh, because if you import a module as @testable, you are able to test all the stuff marked as internal. Which in a way makes sense, because internal means, well, accesible to the module, so it is kind of expected that if you import the module for testing, you should be able to test it fully and properly, with tests that have the same access privileges as the rest of the module.

But, on the other hand, it smells a little. Maybe it is just the mantra “test only public behaviour”, which I am also guilty of repeating over and over again, voicing out its concerns.

TDD Support

I kind of recall reading somewhere or watching in one of the WWDC videos that there is some kind of improved support for TDD in Xcode 7.

All I can see is that, when showing the Assistant Editor, there is an option in the Navigation Bar, or Counterparts bar, or whatever that’s called, that provides a shortcut to the Tested class. But I couldn’t make it work, maybe just because I was trying to TDD the crap out of a struct and not a class (how to choose between those two is a matter of another lengthy post coming up soon).

On a side note

I love the new font in El Capitan. Source code looks very pretty on a retina display.

I guess reaching a certain age makes you reflect on stuff like the meaning of life or the purpose of your work. Not much can be done about the first of those concerns, and if you want to make a somehow decent living, I am afraid you can not do too much about the second either.

However, if you are a Sexy Software Engineer, there is something you can do to fulfil your heart’s desire: open sourcing something.

It does not need to be your life’s work, it does not need to be something that will change the way software is developed, or end world hunger. A repo in github is more than enough.

Finite State Machines

At this point you are probably wondering if this is an actual post about actual software or not. Yes, it is. This is all about State Machines.

State is my favourite design pattern, by far. The first time I heard the words “design pattern” was when I was introduced to State. It was my first day in my first job as an “engineer” (which I later understood was a very different thing as being a “programmer”). To this day, I still remember how I felt when my team lead was explaining it to me: it was a mix of incredulity, fear of the unknown, and a more specific fear of being fired as soon as everyone noticed I was not understanding a single word the team lead was saying.

What problem do State Machines fix?

Indeed.

I guess the easiest way to describe it would be this:

The State Pattern allows objects to behave in different ways depending on their internal state

A simple example of an object that behaves in different ways depending on its internal state might be a play/pause button. If you press the button while it is in the “play” state, whatever is being reproduced will be paused. If you press again, playback will start again.

Now imagine the same button, with another two or three states. Then, the logic to handle the button will start getting more complicated. You might need a switch statement to handle it, you might even need to nest if clauses. In any case, your logic gets quite complicated, and therefore your code will get more error prone and difficult to maintain.

How do State Machines fix that problem?

Instead of having complex logic to handle the different states, declaring a State Machine is just declaring a set of States and the transitions between them.

Transitions are just links between an initial and a final state. Now, it is just a matter of figuring out a way to to trigger those transitions, in order to change the object behaviour.

Turnstile

Turnstile is a lightweight implementation of the State pattern in Swift.

The difficult solution

Imagine you need to develop an application that calculates a company’s payroll. Let’s assume that we have three different roles within the company (Developer, Systems Architect, Development Manager, and since this is a modern cool and hip company that does scrum, a Product Owner), and that different roles have different salaries.

The simplest approach

Well, you could argue that it does not actually matter too much, when calculating the payroll, if an employee is a Developer or a Systems Architect. So, one sensible approach might be to model all employees as instances of a class like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

enumRole{

caseDeveloper

caseSystemsArchitect

caseDevelopmentManager

caseProductOwner

}

classEmployee{

private(set)varname:String

private(set)varrole:Role

private(set)varsalary:Int

init(name:String,role:Role,salary:Int){

self.name=name

self.role=role

self.salary=salary

}

}

Now, calculating the payroll is just a matter of doing something like this:

Now, there are different kinds of Employees. To me, that means that each of those “kinds” has to be modelled by a different class. Why? Because they represent different behaviours. As you know, a PO does not do the same things a Developer does.

However, it is true that I am only interested in part of the behaviour of those different kinds of Employees. That is already abstracted by the interface!

Is there repetition? Yes, apparently, but I wouldn’t call it repetition, I would call it specialisation. If there is something else to be taken into account when calculating a salary (for example, manage,went might have part of their salaries payable in shares dividends and whatnot), the specific class that models a PO can implement that specific behaviour.

Also, this solution improves encapsulation. The responsibility of calculating each employee’s salary is well encapsulated, and is completely opaque to the calculatePayroll method.

Summary

Often times, a flexible solution requires more code than a simple one. Well, that’s life, I guess: if you want something done properly, you will need to put some serious work into it. It does not matter if it is installing a new fridge in your kitchen, or writing a new method in your code.

But the key here, again, is that being able to identify the right abstractions makes a huge difference in the scalability, modularity and cleanness of your code.

But wait, there is more! (I love the way my blog’s theme formats quotes, so I

Enumerations in Swift are first-class types in their own right. They adopt many features traditionally supported only by classes, such as computed properties to provide additional information about the enumeration’s current value, and instance methods to provide functionality related to the values the enumeration represents.

But wait, there is even more!

Enumerations can also define initializers to provide an initial member value; can be extended to expand their functionality beyond their original implementation; and can conform to protocols to provide standard functionality.

Yes, if you ever had to write Objective-C for a living, sooner or later you would find yourself in a spot where you would need to loop all the values in an enumeration.

It was not a big deal, because, well, Objective-C enumerations where collections of integers. So all you had to do was end the enumeration with some sort of marker, that indicated you that you were done.

Well, Swift is different. And this time, that’s for the best. Consider an enumeration like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

enumApplianceForSale: Int{

caseVacuumCleaner=0

caseWashingMachine

caseDryer

caseDishWasher

caseCofeeMaker

caseWaterBoiler

caseFridge

caseToaster

caseWaffleMaker

caseRiceCooker

}

Would there be any safe and maintenable way to loop all the values in that enumeration? Indeed, there would be, thanks to Swift’s Sequences and Generators.

Magic? No! All it takes in some adventurous development backed up by the proper amount of tea or coffee.

How does it work?

Thanks to a combination of NSUserActivity and the OS that sends instances of those activities back and forth between devices. But that is not the best part. The best part is that NSDocument, UIDocument, NSResponder and UIResponder (and therefore all UI classes on both OS X and iOS) have a new property called userActivity which is, surprise, of NSUserActivity type.

So basically, all you have to do, is create a new instance of NSUserActivity in the view / view controller / window / document that you want to be advertising itself as allowing Handoff. The system will take care of sending that activity to other instances of your app in other devices.

After that, you will also need to add a couple of methods to your application delegate, and done!

By the way, Handoff is allowed between multiple instances of iOS apps, between iOS apps and OS X apps, and even between apps and websites.

Neat! How can I support Handoff in my app?

In order to be able to implement Handoff in your Mac / iOS app, all you need to do is…

The system will call becomeCurrent in the view controller automatically if said view controller is in the view hierarchy, but if it is in transition, it will call it after the transition has been completed. Why should you care about that? Because calling becomeCurrent, starts advertising the activity (which is what you are supposed to want, by the way).

Also, when the view controller is removed, or in general, when the system decides that the activity is not needed anymore, it will call invalidate in the activity.

Put information in the activity

Usually, you would want to put some context into the activity. After all, that is the way you will be able to recreate the state in the destination app. You can do that by putting information in the activity’s userInfo dictionary.

In order to do that you should override updateUserActivityState in your UIResponder subclass:

You can put in that dictionary anything that can be serialised to a plist file, in other words, the usual suspects: NSArray, NSDictionary, NSString, NSURL… you get the idea. Be frugal, though, the information you put in the dictionary has to travel the interwebs to reach other devices, you might want the payload to be as light as possible.

Allow your app to reconstruct its state from an activity

This is the neatest part of the whole thing. In your app delegate, the system will call application:willContinueUserActivityWithType. That’s the moment when you need to provide visual feedback to the user indicating that something is about to happen. For example, that would be the perfect moment to start transitioning to a new view controller.

Now, for each call to willContinueUserActivityType, the system guarantees that there will be a call to either a success or an error handler.

The success handler will be called when the system fetches the user activity. The system will pass a block that you will have to call yourself, passing it an array of whatever you want to respond to that activity (in most cases, that would be an instance of the VC you created in the previous step).

Now, in your MainListingViewController, the system will call restoreActivityState. That’s where you can recreate your UI state, according to whatever you receive in the activity’s userInfo. You can also call this method manually if you need to.

Swift

1

2

3

4

5

6

7

8

public overridefuncrestoreUserActivityState(activity:NSUserActivity)

{

//don't forget to call super!!!

super.restoreUserActivityState(activity)

letuserInfo=activity.userInfo

loadDataWithCategory(userInfo["category"])

}

If the system can not fetch the user activity, instead of continueUserActivity, it will call didFailToContinueUserActivity in your app delegate

Warning! The post title might be a little bit misleading. Or not. Read on, and decide.

In the coming paragraphs I am going to look at a few different issues like Swift-Objective-C interoperability, Swift extensions, and the one that actually provides the post title: how relying upon the right abstractions improves code quality and therefore maintainability.

The problem

The difficult solution

I hate (not) to make this about me, but I spend most of my time dealing with native clients that consume content from online video platforms (aka OVPs). In other words, I spent an awful lot to time building lists of Movies, TV Shows and whatnots.

For this particular difficult solution, I need to display a list like this:

The list contains two different kinds of “stuff”: movies and tv shows. To make things a little bit more (opening air quotes) interesting (closing air quotes), both Movies and TVShows are objects modelled as good old Objective-C classes, and I am not allowed to modify the source code of any of those two classes.

Ugly, yes, but Marines don’t do, Marines make do, and so on and so forth.

Now, seriously, this is more evidence supporting a concept I am trying to get across in almost every post. Start with something simple, something that gets the job done. Then look at it carefully, with a critical eye, and you will see all the code smells and bad design decisions jump off the screen, right towards you.

What’s wrong with that? Why is that ugly?

Here is the culprit: isKindOfClass. If you write Java for a living, it would be instanceof. In Swift, it would be the is operator.

YMMV, but I am going to say it as clear as I can: checking for a type at runtime is a code smell. A nasty, stinky code smell.

I know, in theory, there is a reason why isKindOfClass, instanceof and similar are part of the frameworks. In practice, I still have to find myself in a situation where relying on checking the actual type of an object does not stink, and I still have never found myself in a situation where checking the type at runtime was the best possible solution.

How can this be solved in an elegant way?

Well, as usual, taking a step back, and looking at the big picture. What is it that I am trying to achieve? Displaying Movies and TV Shows in the same listing, right?

Yes, and no. What I actually want to do is list a collection of strings. I should not care about what is actually producing those strings, about what it actually is, I should only care about how it behaves.

That is the key concept here: your abstractions would not focus on what things are, but on how things behave.

So, back to my example. If I shift from Movies and TVShows, to something-that-holds-the-data-needed-to-be-presented-in-the-listing, my listing would only have to use one entity, one abstraction.

Step 1. Declare a protocol.

I assume naming might be off. The goal is providing a method that returns the content that we want to display in the cells, already formatted properly as a single string.

Swift

1

2

3

4

protocolListItemPresenter

{

varcellContent: String{get}

}

Step 2. Declare a couple of extensions to Movie and TVShow

Extensions can be used to enforce protocol compliance. This is what The Book has to say about that:

Extensions add new functionality to an existing class, structure, or enumeration type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling).

That is just what we did. Without touching Movie and TVShow, we enforced them to implement a protocol. Even better, notice how Movie and TVShow are written in Objective-C, while the extension is Swift. Neat!

Step 3. Implement the listing data source in Swift.

This is necessary. Only Swift code can use the new features in Swift (like Generics or Extensions). So this one is kind of a no brainer. But Swift is fun, so I call that a win-win!

What on earth is Dependency Injection?

Every time I have to explain what is Dependency Injection, I can’t avoid picturing myself as one of those cheap comedy characters, torn between two little instances of myself siting on my shoulders, one wearing all white, the other one wearing all red.

The one in white is whispering to my ear “provide some background, start the Dependency Inversion Principle”. The one in red,though, will be jumping up and down, shouting “tell him about passing everything your class might need in the constructor”.

Yeah, I have a rich complex inner life.

The Dependency Inversion Principle

Let’s do the right thing, and start from scratch.

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.

B. Abstractions should not depend on details. Details should depend on abstractions.

There you have it, the Dependency Inversion Principle in all its glory. Obviously, if you throw that to anyone’s face, you should expect at least some eye-rolling, if not some head banging (them banging your head against the nearest wall).

In a nutshell, what the principle states is that both high and low level components should depend on the same abstraction. More about that later…

Riiiiiight, but what is Dependency Injection?

Basically, it is a pattern. Not one of the patterns in the GoF, but a pattern nonetheless. A pattern employed to facilitate that both high level and low level components depend on the same abstraction, aka the Dependency Inversion Principle.

Riiiiiiight, would you mind providing an example, smartass?

First, no problem. Second, mind you colourful language, please.

But you have a point. Here is an example of a very simple multi-layer app. There is a service layer that performs operations against an specific service (a service might be an actual remote service, or just a file on disk, let’s assume for the shake or the argument that, in this case, it attacks a remote service), and a business layer on top of it that provides a domain-specific API.

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

/*

* Service Layer. This is the lower layer in the app's

* layer design. It knows about the specific way data

* is stored in a particular service.

*/

class ConfigurationService {

func getValue(key: String)->String {

//attack configuration service and return the value

return "valueForKey" + key

}

func getValues(keys: [String])->[String] {

//attack configuration service and return the value

return keys.map({return "valueForKey" + $0})

}

func getValue(key: String, defaultValue: String)->String {

//attack configuration service and return the value

return key

}

}

/*

* Business layer. This is the top layer, and provides

* semantic, domain specific APIs. It uses the

* ConfigurationService

*/

classConfigurationManager{

private final letservice=ConfigurationService()

funcgetAuthenticationEndPoint()->String{

//Do some business logic, like checking caches and wahtnot

returnservice.getValue("authenticationEndPoint")

}

funcgetLocalCurrency()->String{

//Do some business logic, like checking caches and wahtnot

returnservice.getValue("localCurrency")

}

funcgetIconURLs()->[String]{

leticons=["menuIcon1","menuIcon2","menuIcon3"]

returnservice.getValues(icons)

}

}

Quite straightforward, right? Indeed. The problem here is, what happens if we need to change the way the service layer works? What if we want to grab the configuration from a file on disk, instead of a remote service, or even worse, decide what to do at runtime?

Yeah, we are in a bad situation. Why? Because there is a hard dependency here. The ConfigurationManager depends directly on the ConfigurationService. Those two classes are tightly coupled, the manager can not work without the service.

Sweet. You are good at describing code smells. What about a solution, please?

Sure, no problem. Dependency Injection to the rescue! No, wait! Dependency Inversion Principle to the rescue!

First, I will try to find an abstraction both the manager and the service can depend upon.

Swift

1

2

3

4

5

6

7

8

/*

* The abstraction everyone will rely upon

*/

protocolConfigurationService{

funcgetValue(key:String)->String

funcgetValues(keys:[String])->[String]

funcgetValue(key:String,defaultValue:String)->String

}

Second, I will make my service implement the ConfigurationService protocol.

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

/*

* Service Layer. This is the lower layer in the app's

* layer design. It knows about the specific way data

* is stored in a particular service.

*

* It implements ConfigurationService

*/

classLocalConfigurationService: ConfigurationService{

funcgetValue(key:String)->String{

//attack configuration service and return the value

return"valueForKey"+key

}

funcgetValues(keys:[String])->[String]{

//attack configuration service and return the value

returnkeys.map({return"valueForKey"+$0})

}

funcgetValue(key:String,defaultValue:String)->String{

//attack configuration service and return the value

returnkey

}

}

Now here comes the part where we all facepalm in sync, because suddenly, the concept “Dependency Injection” makes sense. The Dependency (in this example, remember, it was the ConfigurationService) will be injected into the ConfigurationManager as a parameter in the constructor. But wait, there is more! The ConfigurationManager will not hold a reference to an specific dependency, but to an abstraction (the Configuration interface).

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

/*

* Business layer. This is the top layer, and provides

* semantic, domain specific APIs. It is not aware of

* any specific class, but of an abstraction of the service

* (in this case a protocol)

*

* Note how the reference to the service is "injected"

* in the initializer

*/

classConfigurationManager{

private final letservice:ConfigurationService

init(service:ConfigurationService){

self.service=service

}

funcgetAuthenticationEndPoint()->String{

//Do some business logic, like checking caches and wahtnot

returnservice.getValue("authenticationEndPoint")

}

funcgetLocalCurrency()->String{

//Do some business logic, like checking caches and wahtnot

returnservice.getValue("localCurrency")

}

funcgetIconURLs()->[String]{

leticons=["menuIcon1","menuIcon2","menuIcon3"]

returnservice.getValues(icons)

}

}

This last bit is important, so I am going to repeat it. The ConfigurationManager depends on an abstraction now. It is not aware of which actual service it is using, and it actually does not give a damn about it.

Summary

Dependency Injection decreases coupling, and improves the flexibility and modularity of all designs. And it is a neat term that will make you look cool if you use in front of your colleagues.

Today we are going to go through one of the five tools that every Object Oriented Designer, or just anyone not wanting his code to become a loaded gun pointing at her head, should have in her toolset: the Open/Closed Principle.

The Open/Closed Principle is one of the most mentioned, but yet most misunderstood, of the five SOLID principles. I am sure you are fed up with reading the definition all around the interwebs, but here it is anyway:

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

Say what!?

Open for extension, but closed for modification. Neat. But, what does that mean? Let’s rephrase the Principle a little bit:

We should be able to modify the behaviour of a piece of code without changing the actual code that implements it.

In other words, we should have magic powers, or superpowers, or be able to bend the space-time continuum.

Having superpowers would be neat. Can I have some?

Sure, it would be neat. But it is definitely out of the scope of this post.

Let me rephrase. How can my code be open for extension but closed for modification?

Let’s go through a real life example. Real life, like in “code extracted from an actual codebase my team has to maintain”. Let’s pretend that the fact that I personally wrote the offending piece of code does not matter.

The problem

I mostly work with OVPs (that’s Online Video Platforms). I build those pesky apps that some TV providers deliver to their subscribers, and allow said subscribers to watch TV on their devices.

An Electronic Program Guide is a list of what is going to be broadcasted during a particular range of dates/times. Let’s pretend this is what I need to display:

Bear with me on this one, please.

As you can see, the list needs to display Movies, TV Shows, and Live events. When the user taps a particular Program, the app needs to transition to a “details” view, which is, obviously, different (different content and different layout, and even different business logic) according to the type of Program the user selected.

For historical reasons, and some practical reasons, the model object that was provided with in order to build that listing looks similar to this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

/*

The backend provides a Program object in the services response.

Also, it provides a "type" that identifies the type of program.

*/

enumProgramType{

caseMovie

caseEpisode

caseLiveProgram

}

// Simplified Program, for the shake of the example.

classProgram{

private(set)vartitle:String

private(set)vartype:ProgramType

init(title:String,type:ProgramType){

self.title=title

self.type=type

}

}

Yes, you can argue than all my troubles will end if I looked at the right abstraction, and if I did not need to rely on that “type” property. And I would agree with you: remember, there are historical reasons behind this. Anyway, all this “look at the right abstraction” thing is probably matter of another post.

But, on the other hand, relaying on the right abstraction does not change the fact that I need to navigate to different views according to the type of content I need to display.

The simplest possible solution.

I am a big fan of keeping things simple. When you keep things simple, code smells, bad designs, and bad solutions just popup in front of you when you look at the code, jumping out of the monitor, waving their arms, screaming “refactor me, refactor me!”

So, the simplest implementation that would get the job done would be:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/*

Function to be called when the user taps a program.

This shall launch the a different view controller according

to the content that needs to be displayed.

*/

funcnavigateToDetails(program:Program){

switchprogram.type{

case.Movie:

println("It is a movie, navigate to Movie Details")

case.Episode:

println("It is an Episode, navigate to Episode Details")

case.LiveProgram:

println("It is a LiveProgram, navigate to Live Program Details")

}

}

letsampleMovie=Program(title:"The Quiet Man",type:.Movie)

letsampleEpisode=Program(title:"CSI: S47E03",type:.Episode)

navigateToDetails(sampleMovie)

//navigateToDetails(sampleEpisode)

Riiiiiiiight, a switch.

Switch is bad

No matter what they tell you, no matter what you see, switch clauses are usually a code smell. And in this particular case, ermahgawd, it is just bad. I wrote that code, and I still want to punch myself in the face overtime I see it. But why?

Well, this will not escalate well. First, and most obvious, Program is poorly designed, it is the wrong abstraction, and to workaround that bad design, it exposes a type to help identify what it actually represents. That is clearly meant to change.

But, the worst is about to come. What if I need to deal with a new type of program? I would need to update that switch. There is no way to extend this code that does not imply editing the navigateToDetails function.

This code is not open for extension and closed for modification.

Again, the simplest possible solution clearly exposes two code smells: first, Program is the wrong abstraction, or at least it is poorly designed, and second, the initial design is not easy to extend.

The better solution, open for extension and closed for modification

Let’s assume that Program is not going to change now. It will, but not at this precise moment.

If you look at the first implementation of the navigateToDetails function, you will see how all the business logic that deals with navigation is in there. That function checks the program type, and launches the command needed to navigate to the desired destination. What I want, is find a way to delay those decisions as much as possible. That way, I can deal with the problem in a generic way here.

The first step to fix my problem (remember, I want to be able to navigate to different views according to the type of Program the user selects) starts with declaring a protocol that abstracts the details of how I want to perform that navigation.

Swift

1

2

3

4

5

6

// Protocol that abstract the behaviour:

navigating tothe view that contains the Program'sextended info.

protocolRouter{

funccanHandleProgram(program:Program)->Bool

funcnavigateTo(program:Program)

}

Then, I will have different implementations of that protocol. Each of those concrete implementations will deal with the details of how to navigate to the desired destination, and more importantly, they will provide a way to decide if that particular implementation is supposed to handle a Program or not.

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

// Implementation of the Router protocol that navigates to the

Movie extended info

final classMovieRouter: Router{

funccanHandleProgram(program:Program)->Bool{

returnprogram.type==.Movie

}

funcnavigateTo(program:Program){

println("It is a movie, navigate to Movie Details")

}

}

// Implementation of the Router protocol that navigates to the

Episode extended info

final classEpisodeRouter: Router{

funccanHandleProgram(program:Program)->Bool{

returnprogram.type==.Episode

}

funcnavigateTo(program:Program){

println("It is an Episode, navigate to Episode Details")

}

}

// Implementation of the Router protocol that navigates to the

LiveProgram extended info

final classLiveProgramRouter: Router{

funccanHandleProgram(program:Program)->Bool{

returnprogram.type==.LiveProgram

}

funcnavigateTo(program:Program){

println("It is a LiveProgram, navigate to Live Program Details")

}

}

That last part is the key of the whole refactoring. Notice how I can inject (or in less fancy words, pass as a parameter) a list of all the available implementations of the Router. My navigateToDetails function will loop those, passing them the Program. If it finds any implementation that can deal with the Program passed as parameter, it will ask the implementation found to proceed and navigate to… where? That’s the thing! The navigateToDetails function does not know where, because it doesn’t need to know.

Delay all decisions!

I recall reading, some time ago, that good Object Oriented Design consisted in finding ways to delay decisions. I only agree with that up to a point (I guess I have been a victim of over-engineered systems more than once), but I think it makes a good rule of thumb. If a particular part of your system knows too much about others, maybe it is time to rethink it.

But I digress. The whole point of this post was implementing a solution to a problem in a way that allows easy maintenance, and simplifies scalability.

Summary.

Object Oriented Design is all about trade-offs. Simple code usually gets the job done, but sometimes simplicity in the code brings along poor maintainability. Sometimes, ten lines of code get the work done, but sometimes you need to substitute those ten lines by a hundred lines, as long as those hundred lines provide a solid, clean and maintainable solution.

And, did I mention that unit testing the second solution is way easier?

Code samples.

You can get a couple of Swift playgrounds containing the source code to this post on Github