Category: CodingAdventures

I was re-reading Effective Java (it is a rainy Sunday afternoon in Vancouver, and if you are stuck at home, and you happen to be European, and therefore you don’t really care about what Americans call “football”, re-reading Effective Java is not as bad as it sounds) when I soon stumbled upon an example that I think highlights the elegance of Swift (and, to be completely fair, also Kotlin’s).

Effective Java’s Item #2 says: Consider a builder when faced with many constructor parameters. Which makes total sense, if you ask me.

I am not going to discuss or justify the Builder Pattern now, but let’s just assume that it is more than justified.

The canonical implementation of the pattern, and I am going to take the liberty of using the code sample used in Effective Java without any modification, would read like the following (servings and servingSize are the only mandatory parameters, the rest are all optional)

Java

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

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

public class NutritionFacts {

private final int servingSize; //required

private final int servings; //required

private final int calories; //optional

private final int fat; //optional

private final int sodium; //optional

private final int carbs; //optional

public static class Builder {

//Required

private final int servingSize;

private final int servings;

//Optional

private int calories = 0;

private int fat = 0;

private int sodium = 0;

private int carbs = 0;

public Builder(int servingSize, int servings) {

this.servingSize = servingSize;

this.servings = servings;

}

public Builder calories(int val) {

calories = val;

return this;

}

public Builder fat(int val) {

fat = val;

return this;

}

public Builder sodium(int val) {

sodium = val;

return this;

}

public Builder carbs(int val) {

carbs = val;

return this;

}

public NutritionFacts build() {

return new NutritionFacts(this);

}

}

private NutritionFacts(Builder builder) {

servingSize = builder.servingSize;

servings = builder.servings;

calories = builder.calories;

fat = builder.fat;

sodium = builder.sodium;

carbs = builder.carbs;

}

}

class Untitled {

public static void main(String[] args) {

NutritionFacts cocaCola = new NutritionFacts.Builder(240,8)

.calories(100)

.sodium(35)

.carbs(27)

.build();

}

}

If we follow the pattern to the letter, it translates into Swift like this:

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

49

50

51

52

53

54

55

56

57

58

59

60

61

62

final class NutritionFacts {

private let servingSize: Int

private let servings: Int

private let calories: Int

private let fat: Int

private let sodium: Int

private let carbs: Int

init(builder: Builder) {

servingSize = builder.servingSize

servings = builder.servings

calories = builder.calories

fat = builder.fat

sodium = builder.sodium

carbs = builder.carbs

}

class Builder {

let servingSize: Int

let servings: Int

private(set) var calories = 0

private(set) var fat = 0

private(set) var carbs = 0

private(set) var sodium = 0

init(servingSize: Int, servings: Int) {

self.servingSize = servingSize

self.servings = servings

}

func calories(value: Int) -> Builder {

calories = value

return self

}

func fat(value: Int) -> Builder {

fat = value

return self

}

func carbs(value: Int) -> Builder {

carbs = value

return self

}

func sodium(value: Int) -> Builder {

sodium = value

return self

}

func build() -> NutritionFacts {

return NutritionFacts(builder: self)

}

}

}

let facts = NutritionFacts.Builder(servingSize: 10, servings: 1)

.calories(value: 20)

.carbs(value: 2)

.fat(value: 5)

.build()

Which is a lot of boilerplate, no matter how you look at it.

We have discussed Swift’s Default Parameters before in this blog, but in the context of Dependency Injection, in particular when focusing on testability.

But the thing is that Default Parameters, like many other Swift artifacts (or constructs, or whatever is the right word to refer to “stuff that Swift provides and makes your life easier”) can make code much more concise, readable and easier to understand and reason about while removing some of the bloating that certain languages (I’m looking at you, Java) are known for.

Because when providing default values to all the optional parameters, this is how our NutritionFacts look.

In the previous post, we discussed how protocols 1 are the foundation of polymorphism, and how using protocols we can define a contract, an expectation, that can be implemented in many different ways.

Today we are also to explore how we can use protocols as a way to use code that does not exist yet, as a boundary between what we know (our code) and what we don’t know (other people’s code).

In an ideal world (maybe not ideal for everyone, but that would be a different discussion) we don’t develop our software in isolation. We have team mates, or we use modules or frameworks developed by other teams within the same company.

Some time ago, I was with a time developing a set of Video On Demand applications. We had to implement a new feature: add support for recommendations based on user’s content consumption habits. The recommendations engine was not developed yet, in fact there was no team assigned to build it at that time.

We knew were our side of the solution started and ended. We knew we were going to need to tell the recommendations engine that a user had watched a particular item, and we were going to need to get a list of recommended items from the engine.

We started by defining our own interface for that recommendations engine. We looked at the problem from ur side of it, and wrote the interface we wished the recommendations engine had.

Did we know how the actual interface of the actual recommendations engine would look? Not at all. Did we care? We did not.

But we could start working on our side of the solution using fake data.

Having a clear boundary, clear separation between our side and their side, allowed us to build our side completely decoupled from the recommendations engine.

Having a clear boundary also gave us the confidence that we would be able to adapt to whatever the actual interface of the recommendations engine would look. And why I mean by adapt is literally write an adapter between our interface and the actually interface of the engine, if necessary (see the Adapter Pattern)

Also, having a clear boundary allowed us to unit test our solution from day one, giving us the confidence we needed to move forward fast.

It’s not rocket science. But it is worth remembering that protocols are not just those things that you use for table views data sources and delegates, but that they are probably the most powerful tool in our reach.

I have never been a fan of how the Cocoa frameworks use the word protocol instead of interface. ↩︎

Back in the old days, people used to communicate with each other by shouting.

Swift

1

2

3

4

5

6

7

struct Person {

let name: String

func sendMesage(content: String) {

print(content)

}

}

But soon, people found that shouting was not practical. The receiver of a message could just be too far away, or sleeping, so humanity invented written messages. And so snail mail was born.

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

struct Person {

let name: String

let mail = SnailMail()

func sendMesage(content: String) {

mail.send(message: content)

}

}

struct SnailMail {

func send(message: String) {

print("sending snail mail. ", message)

}

}

Fast forward a few hundred years, to the early ages of the internet. Someone, somewhere, invented email, so now people could communicate like this.

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

struct Person {

let name: String

let emailClient = Email()

func sendMesage(content: String) {

emailClient.send(message: content)

}

}

struct Email {

func send(message: String) {

print("sending email ", message)

}

}

Soon, people realized that even though email was great, there were other forms of communication. What’s even more remarkable, people were happy sending emails, but they soon realized that what they really wanted was to be able to do something slightly different. Instead of sending emails, they just wanted to send messages.

Some of those messages would be emails, some of them would be snail mail, some others might even be some unknown technological marvel soon to be discovered. But what all people knew is that they did not wan to be constrained by being able to send emails and only emails.

And here is when people realized that the way they had been approaching communications was slightly unadaptable.

One of the few software engineers on the face on earth at that time, decided to do something about it. She started thinking about what people wanted, and why they could not have it, and soon realized that the actual problem was that there was a hardcoded dependency between a Person, and the way that person was able to communicate.

Our hero also realized that the reason why that was a problem was that what people really wanted was freedom of choice, and flexibility, and being able to send messages by multiple different mechanisms, not only email.

And that made her think: “maybe what people expect are not things, but behaviours”. Indeed, People seemed to have a clear expectation: “we should be able to send a message”, but different people wanted that expectation to be fulfilled differently.

Our hero thought “what people want to rely upon is an abstraction, not something specific.”1

So our hero started building her solution around an abstraction: a protocol defining a behaviour.

Swift

1

2

3

protocol Sendable {

func send(message: String)

}

That allowed our hero to model a couple of specific implementations of that behaviour 2. For example, an email, an SMS, an iMessage (aka Apple Message, to avoid lowercasing a class, apparently all our hero firmly believes in coding standards)

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

struct Email: Sendable {

func send(message: String) {

print("sending email ", message)

}

}

struct SMS: Sendable {

func send(message: String) {

print("sending SMS ", message)

}

}

struct AppleMessages: Sendable {

func send(message: String) {

print("sending iMessage ", message)

}

}

So now, a Person could be taught to blindly rely on the abstraction our hero modelled, trusting it to know how to fulfill her expectations.3

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

struct Person {

let name: String

/**

* Person does not know exactly what it depends on. All it knows is that it depends on something that willl provide a send() method (as declared in the protocol)

*/

let sendable: Sendable

/**

* Inject the dependency

*/

init(name: String, sendable: Sendable) {

self.name = name

self.sendable = sendable

}

/**

* And rely on the abstraction, provided as a parameter (aka injected), to do its thing

*/

func sendMesage(content: String) {

sendable.send(message: content)

}

}

That way, Cesar can send emails while Jodelle can send emails, or a hipster can send a Messenger Pigeon.

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

/**

* Cesar Sends SMSs

*/

let smsSender = SMS()

let me = Person(name: "Cesar", sendable: smsSender)

me.sendMesage(content: "Hey Jodelle!")

/**

* Jodelle Sends Emails

*/

let emailSender = Email()

let jodelle = Person(name: "Jodelle", sendable: emailSender)

jodelle.sendMesage(content: "Hey Cesar!")

/**

* Hipsters send pigeons

*/

struct Pigeon: Sendable {

func send(message: String) {

print("sending this message with a pigeon ", message)

}

}

let pigeon = Pigeon()

let aHipster = Person(name: "It's ironic!", sendable: pigeon)

aHipster.sendMesage(content: "Hello world")

Our hero was satisfied with her implementation of the solution, specially because she realized that this design allowed her to provide as many means of sending messages as she wanted, without having to change the way a Person sends a message.4

Also, our hero soon realized that she could only test that messages are actually sent, by providing a very specific type of Sendable that did not actually send any message.5

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

/**

* Mock objects usually do not have any actual behaviour, other than fulfilling an expectation. In this case, we want this mock object to mark itself as "sent" when the send() method is called

*/

class MockSendable: Sendable {

var sent: Bool = false

func send(message: String) {

sent = true

}

}

/**

* Now we inject the mock into a Person, ask that person to send a mesage, and check that the mock has been marked to "sent". That, in the context of unit testing, is called the AAA (Arrange, Act, Assert)

*/

//Arrange. Create a Mock, and inject it

let mock = MockSendable()

print("mock initial state ", mock.sent)

let personUnderTest = Person(name: "Test", sendable: mock)

// Act. Call the method that triggers the behaviour we want to test

personUnderTest.sendMesage(content: "Testing testing")

// Assert. Verify that our expectation (the mock is marked as sent) has been fulfilled. This way, we can test Person in isolation, without any dependencies

print("Did the mock get called? ", mock.sent)

And that’s the power of protocols. A protocol defines a contract, declares a behaviour, but does not define the way that contract of behaviour is implemented. A protocol is abstraction, and the details, the nitty gritty of how those contracts or behaviours are implemented are left to concrete implementations of the protocol.

Relying on abstractions instead of concretions, in general, makes designs more decoupled, open for extension and closed for modification, and highly testable.

Today I learned that something that has been annoying me significantly when working in Swift, has a very simple solution, if only I knew my tools better.

This is a class. I have written a bunch of classes similar to this one:

Swift

1

2

3

4

5

6

7

finalclassItem{

private letid:String

init(id:String){

self.id=id

}

}

That self in the constructor, annoys me to no end. I like how self is explicit in Swift, I think it makes the code more readable, less verbose, simpler. So, having it in the constructor, again, annoys me.

The solution is quite simple. Functions can have not only parameter names, but also argument labels.

Each function parameter has both an argument label and a parameter name. The argument label is used when calling the function; each argument is written in the function call with its argument label before it. The parameter name is used in the implementation of the function. By default, parameters use their parameter name as their argument label.

Fair warning: Coming up with an example relevant enough to illustrate the topic, but simple enough to fit in about 1500 words is challenging. Take this code as a starting point, as a way to illustrate a discussion, and not as a drop-in solution ready to apply to a codebase.

Also, this solution can be applied to collection views. But again, for brevity, I will only discuss table views.

The previous post in this very blog was about going from the abstract and generic to the concrete and specific. It was, in a way, about specialising something abstract and generic, by subclassing it and providing a specific implementation for a specific type.

The sample code I used was more or less copied and pasted (with some info removed to protect the innocent) from the codebase I am currently maintaining. At the time I posted it it was holding well, but soon after that post I started having the feeling that there had to be a better way.

The problem

The problem I am trying to solve is a fairly common problem when it comes to iOS development: presenting lists of data without having an a lot of boilerplate code repeated again and again.

The usual way to present a list would be having a UIViewController that implements some or all of the methods in UITableViewDataSource.

That could be fine if there was only one data collection to render on screen, but usually, iOS apps are a sequence of screens that present data collections. Not only that, but usually, those screens are not that different from each other.

Sometimes, what changes from one data screen to another is the way a data item is rendered on screen (different UITableViewCells), some other times what changes from one screen to another is the presence or absence of section headers, or section footers, or both headers and footers.

So, if we approach the problem trying to abstract it as much as possible, what we would have would be a core behaviour (presenting data) that we might want to customise (i.e. adding headers or footers). And to make things more interesting, we want to do that in a way that reduces boilerplate and duplication and makes the solution testable.

The solution I have been exploring

The first step would be finding a way to factor out data management from view controllers. First, because it makes sense (a view controller should control a view, not manage a collection of data), and second, because by doing so we can remove a lot of boilerplate and duplication.

There are other solutions, but I am sticking to mine for now, not because I think it’s better, but because, so far, it works for me. Basically, the implementation of the UITableViewDataSource protocol does not populate cells outlets, but provides cells with a model object, and trusts cells to know how to render that model object themselves. Tell, don’t ask!

So let’s start there. Let’s assume we are working on a task manager. We have a Task:

Swift

1

2

3

struct Task {

let title: String

}

And we have a class to manage tasks as flat arrays. In real life, this data manager should be able to handle sections, but, again, for brevity, this one will be all flat:

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

final class FlatArrayDataManager<T> {

fileprivate var data: [T]

init(data: [T]) {

self.data = data

}

convenience init() {

self.init(data: [T]())

}

func itemCount() -> Int {

return data.count

}

func item(_ indexPath: IndexPath) -> T? {

guard indexPath.row < data.count else {

return nil

}

return data[indexPath.row]

}

func sectionCount() -> Int {

return 1

}

}

Now, let’s move to the other end of the problem: the UI. As mentioned, cells will know what to do to render themselves when they are provided with data. We can model that assumption with a protocol that indicates that a cell will accept a model object, and a concrete implementation of that protocol:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

protocol DataSettableCell {

associatedtype DataType

var data: DataType? {get set}

}

extension DataSettableCell {

static func cellReuseIdentifier() -> String {

return String(describing: self)

}

}

final class AwesomeCell: UITableViewCell, DataSettableCell {

var data: Task? {

didSet {

//populate cell, set outlets

}

}

}

A class implementing the required methods in UITableViewDataSource will look like this:

We provide it with a data manager, and a cell type. Notice how the implementation of the cellForRowAtIndexPath method only dequeues the cell, and passes it the model object that corresponds to its index.

So far, none of this solves the actual problem: customising data listings. But it send the foundation for a solution.

What was the problem again?

Let’s say that we have to render two different task lists, one of them without any section headers, and another one with a single section header. Let’s say also that we need a third listing with a section footer.

If we go all abstract, what we want is our datasource to behave slightly differently in different situations, while maintaining a core behaviour unchanged. Or, in other words, what we want is to add behaviour to an individual object without affecting the behaviour of other objects of the same class.

The Decorator Pattern

And that is, literally, the definition of the Decorator Pattern. So, let’s explore the Decorator Pattern a little bit more, and see if it can actually be a good solution to our problem.

The pattern’s intent is clear: extending the behaviour of a certain object, independently of other instances of the same class. That will fit our case: we want some behaviour to remain unchanged but we also want to be able to customise some other behaviours, but only for specific cases.

There is another subtle detail here: the core behaviour, what we do not want to change, happens to be what is provided by the required methods in the UITableViewDataSource protocol, and what we want to customise, happens to be declared in optional methods.

That fits the pattern quite well. The ConcreteComponent could provide the behaviour we don’t want to change, provided by the require methods in the UITableViewDataSource protocol, and we could add ConcreteDecorators for each behaviour we wanted to add or customise.

So, just to recap, there seems to be a one to one relationship between the elements of the pattern and our use case: the Component would be the UITableViewDataSource protocol, the ConcreteComponent would be the Required class, and we can provide ConcreteDecorators that also implement the UITableViewDataSourceProtocol.

We would also need an implementation of the UITableViewDataSource protocol that aggregates an instance of the UITableViewDataSource type, implements all the methods in the protocol and forwards them to the instance it aggregates:

And now we can start encapsulating the different behaviours we want to provide in subclasses of that TableDecorator. For example, if we need to provide a header title for a single section, a footer title for a single section, and header titles for multiple sections:

The beauty of this solution is that now we can add behaviours to the core behaviour of our datasource, in a composable way. Each behaviour would be well encapsulated, which in turn means that it can be easily tested, and it could also be reused eventually.

And what is even better is that we can mix and match behaviours without modifying the code in the core datasource, and without adding any conditional logic.

For example, if we want a table with section header and no footer, we can do this:

That is the way we can compose optional behaviours: by adding them one by one, as layers of an onion, to a core behaviour.

Final words

I have ambivalent feelings about Design Patterns. I do agree that these patterns tend to be overused, and I have found myself a few times at that stage where all you can see are design patterns everywhere, and you try to solve any possible problem with an implementation of the Visitor Pattern.

But if design patterns are taken as what I believe they are, which is just one more tool, being able to identify them, and being able to consider the trade-offs of implementing or not implementing them can make a huge difference in the quality of a codebase.

In this particular example, having a collection of highly cohesive, loosely coupled and highly testable behaviours, that can be applied to modify a core behaviour at will, seems like a win.

I am not a big fan of inheritance. I would never say something like “inheritance is evil”, because inheritance, like composition, is just one of the many tools we can reach for, but in my experience, designs based on inheritance tend to be very rigid.

But here is one particular use case where I think the combination of generics and inheritance can provide an interesting solution.

As usual, the example that tries to illustrate this post is not very good. But it is close to my real use case, so I am going to stick with it.

I try to avoid boilerplate as much as possible. That’s why I try to use a generic implementation of the datasource protocols (UITableViewDataSource and UICollectionViewDataSource) to feed all my listings. I even released those datasources as a framework!

The thing is, there is always going to be some particular listing that does not fit completely into that framework. In particular, those listings that require implementing one of the optional methods.

For example, let’s take a look at tableView:titleForHeaderInSection. Do we need a header in every single tableview? Not really, some table views might not even be sectioned.

That method does not seem something that would belong in a generic datasource, because, well, it is there to provide a solution to a very specific use case.

So we could have a generic implementation of the UITableViewDatasource protocol like this (bear in mind I have over simplified it, for brevity):

Mutability is dangerous and I have been aware of the fact for a long time. However, mutability can be sneaky, and make its way into the code without anyone noticing. Sometimes, with disastrous consequences.

First, a little disclaimer. I am a big fan of dependency injection. I have touched the subject in this very blog maybe too many times. I know it is not a golden bullet, I know it is not the solution to every problem, but still, I believe injecting dependencies is, in general, good.

Once that’s out of the way, let’s move on to today’s story. Imagine a view controller that needs to display data fetched from a backend. The integration with said backend is well encapsulated in a class, abstracted by an interface.

A simplified version of this view controller could look like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

final class ViewController: UIViewController {

private let data: DataService

init(nibName nibNameOrNil: String?,

bundle nibBundleOrNil: Bundle?,

data: DataService) {

self.data = data

super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

}

private func fetchData() {

data.allItems { items in

/**

Provide data to a datasource, or present on screen directly, or...

*/

}

}

}

I like this approach: the view controller is provided with everything it needs to work in the constructor, the origin of the data is well abstracted (it could be a remote server, it could be a local database, it could be core data, we don’t care, because we don’t need to know).

But…

This view controller belongs to a storyboard. Dum dum duuuuum.

Here is another disclaimer. I am not a big fan of storyboards for multiple reasons (and the more I use them, the less I like them). But that does not change the fact that this view controller belongs to a storyboard.

So, now, in order to provide it the data service, you have to do something like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

final class ViewController: UIViewController {

var data: DataService?

private func fetchData() {

data?.allItems { items in

/**

Provide data to a datasource, or present on screen directly, or...

*/

}

}

}

As far as I know, there is no way to avoid the fact that data can not be assigned a value when the view controller is instantiated. No matter how had I tried to work around it, like making the data variable private and providing a public setter, declaring that setter in a protocol and enforcing compliance in an extension, the fact is that, as far as I know, dataService needs to be a variable, and can not be set when this class is instantiated.

And that is a problem. Because if, for example, you have a segue that leads to this view controller, and you forget to set the value in an override prepareforSegue method, data is going to be nil and DataService.allItems() is not going to be called.

And if you have two segues that lead to this view controller, then you have to make sure that you set the value of data in two different places.

And that’s exactly how my rear got bit. I didn’t notice that second segue, so it was possible to instantiate this view controller without data being set.

You might argue, and you wouldn’t be wrong, that it is my fault, that I am the one that was not setting the value of a variable that is necessary for a part of the system to work properly. Yes, but…

If this class was really immutable (like it is in the first sample), the compiler would enforce that for me. If I do not provide a non-nil value to this view controller’s initialiser, the compiler will not build the project.

And that’s important. Because I am not good at remembering details, in particular details that I somehow consider that I should not need to remember.

In any system, in any codebase of a significant size, special cases, exceptions to the rule, and small details that you have to remember, are a recipe for disaster.

Thanks to multiple painful experiences, I have learnt that this apply to everything. If I need to change a url manually before submitting an app for review, there is going to be a moment when I am going to forget, and submit with the wrong url. If an API needs a parameter named data, and returns data in a parameter named values, sooner or later I am going to mess those up. And if I code a class in a way that it can be initialised in an inconsistent state, by code is going to find a way to initialise that class in the most inconsistent state possible.

I won’t day that “mutability is evil”. There is a place for it. But, this week, I got confirmation, one again, that the best way to avoid problems is allowing the compiler to help me as much as possible.

This post is about one of the Design Patterns, the Template Method. Except for the fact that, well, it is actually about somethign competely different.

Some time ago, in a galaxy far far away, the team I was with was building an internal framework. Our code was supposed to be an amalgamation of rainbows and unicorns that the rest of the company would use as a starting point to build highly customised projects. Yes, it didn’t end well.

But something today made reminisce of a particular episode in that era. Fair warning, some details have been changed to protect the innocent and or make my example a little more relevant.

We were building a video player. The requirements were quite simple: the UI should be easily customisable, and playback events should be trackable (i.e. play, pause, progress), and should be handled in a way that it should be easy to integrate with a second screen solution. Mind you, the company’s business domain was online video delivery, so as you could imagine, this was kind of a big deal.

So, off we went to build the thing, machete in hand and bug spray in pocket.

The key piece of the design was a “manager”, a block of logic that coordinated the playback status with the player’s UI state, while offering a default integration with a second screen solution (also developed in-house).

Now, and this is important, we needed to provide that integration with a second screen solution due to internal business reasons, but the design should be open enough so that other teams could provide their own integrations (i.e. AirPlay or Chromecast)

After some lively discussions we decided to provide what we believed complied with all the requirements.

So, this was, more or less, our manager, translated to Swift 3. Because those were still the Objective-C days.

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

openclassVideoPlayer{

init(){

// initialize all the things

}

funcplaybackStarted(){

// To be overriden

}

funcplaybackStopped(){

// to be overriden

}

funcplaybackProgress(){

// To be overriden

}

// Bunch of private methods here

private funcplay(){

// do stuff that needs to be done

// And then allow subclasses to provide their own behaviour

playbackStarted()

}

}

classInHouseSecondScreenVideoPLayer{

overridefuncplaybackStarted(){

// Implementation that uses the in-house thingy

}

overridefuncplaybackStopped(){

// Implementation that uses the in-house thingy

}

overridefuncplaybackProgress(){

// Implementation that uses the in-house thingy

}

}

The idea was simple. We provided the bulk of the business logic in our manager, and subclasses of our manager should be provided for different integrations with second screen solutions.

Basically, we designed an system modelled after the Template Method Pattern.

If a team wanted to integrate this video player with Chromecast, they would just need to subclass our manager, override the extension points we had provided, and go on their merry way. If another team wanted to integrate with AirPlay, they could do the same.

But, what would happen if a team wanted to integrate with AirPlay and Chromecast?

Well, they could subclass our manager with an integration with Chromecast, and then subclass their Chromecast integration with an AirPlay integration that could call super as part of each method that it overrides.

And that’s my issue with this pattern: it is not exactly what I would consider a very open design.

So, what would be the alternative? As usual, it depends.
To begin with, this pattern can be extremely useful sometimes, and provide very elegant solutions to some problems.

But, in this case, and I guess in any case where an open design is the main goal, it might be better to define an interface for each behaviour that we want to be customisable, and inject them.

For example, we could change the previous design to something like this:

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

49

50

protocolSecondScreen{

funcplaybackStarted()

funcplaybackStopped()

funcplaybackProgress()

}

final classInHouse: SecondScreen{

funcplaybackStarted(){

// Implementation that uses the in-house thingy

}

funcplaybackStopped(){

// Implementation that uses the in-house thingy

}

funcplaybackProgress(){

// Implementation that uses the in-house thingy

}

}

final classChromecast: SecondScreen{

funcplaybackStarted(){

// Implementation that uses Chromecast

}

funcplaybackStopped(){

// Implementation that uses Chromecast

}

funcplaybackProgress(){

// Implementation that uses Chromecast

}

}

finalclassVideoPlayer{

private letsecondScreen:SecondScreen

int(secondScreen:SecondScreen){

self.secondScreen=secondScreen

}

// Bunch of private methods here

private funcplay(){

// do stuff that needs to be done

// And then allow let the second screen know

secondScreen.playbackStarted()

}

}

letplayer=VideoPlayer(InHouse())

The original design was not bad. This new design, however, has a couple advantages over the original design.

First, the manager and the different implementations of the second screens are more decoupled. The manager can work with multiple different implementation of the second screen, and those implementations of the second screen can collaborate with something other than the manager.

Second, these implementations of second screens are more cohesive, and therefore are going to be easier to test and maintain in the long term. And this part, in my experience, is extremely important. When classes do one thing and one thing only, and all the logic related to that thing is encapsulated in the same class, it is way easier to go back to it months after the code was written.

And third, and more important, now it is way easier to compose behaviours. For example (and I know this is a bad example, but it helps me illustrate my point), if we were asked to send play/stop events to both our InHouse solution and Chromecast and playback progress events only to Chromecast, we could reuse the implementations we already have, like this.

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

final classAllTogetherNow: SecondScreen{

private letinHouse=InHouse()

private letchromecast=Chromecast()

funcplaybackStarted(){

inHouse.playbackStarted()

chromecast.playbackStarted()

}

funcplaybackStopped(){

inHouse.playbackStopped()

chromecast.playbackStopped()

}

funcplaybackProgress(){

chromecast.playbackProgress()

}

}

letplayer=VideoPlayer(AllTogetherNow())

So, I guess, the whole point of this post is “favour composition over inheritance”.

Except, of course, when inheritance provides a better solution to the problem at hand.

So, on second thought, I guess the whole point of this post is that there are trade offs to every approach. A good engineer should try to choose the approach the solves the problem better, with the information she has at hand at that particular moment.

Note: This post has been seating in my drafts folder for months. It is about a topic that has been discussed over and over in this blog, but I still feel like it can add some kind of value. So here you have it.

Dependency Injection and the SOLID principles have become, one way or another, an important part of almost ever post in this blog. And today’s post is no exception.

In my experience, one of the biggest challenges when it comes to unit testing view controllers is, well, unit testing view controllers.

UIKit tends to make all of us lean towards the “one screen = one view controller” paradigm, which tends to make each and every one of those view controllers sort of a dark hole that swallows everything related to the screen it corresponds to.

Yes, as soon as a view controller starts doing more than just the thing it should do (controlling a view), and starts doing networking, navigation, model state validation, local persistency and whatever elese you throw at it, things begin to get complicated.

Well, there is a solution for that: making view controllers do less. Which can be achieved with the help of our old friend, the Single Responsibility Principle. Tell us more about yourself, old friend!

Every module or class should have responsibility over a single part of the functionality provided by the software

The thing about default parameters is that we can use them to help us factor our code in a cleaner and more modular way.

Let’s say that we have a view controller that needs to present a list of Items, fetched from our backend.

We want our view controller to do just one thing, so we will extract the networking to a separate class. Actually, what we do is separate to a different module whatever is related with providing the view controller with the data it needs to display. (See? Single Responsibility Principle FTW!)

So, we could write our view controller like this:

Swift

1

2

3

4

5

6

7

8

9

10

11

12

13

finalclassList{

letdataLoader=DefaultDataLoader()

vardataSource:DataSource?

overwrite funcviewDidLoad(){

dataLoader.load(completion:dataReceived)

}

private funcdataReceived(data:[Item]?){

dataSource=DataSource(data:data)

tableView.dataSource=dataSource

}

}

This solution is doing the Single Responsibility Thingy properly, but the dependency between List and DefaultDataLoader is hardcoded.

That is an issue, because it is safe to assume that DefaultDataLoader is somehow going to fetch data from the network. Which means that if I want to unit test List, I needs my tests to fetch data from the network, which is in between not optimal and plainly bad.

But why is networking in the tests bad? First, because there is no way to feed the unit tests with custom data, with data that we expect the view controller to handle in an specific way, for example.

Also, because unit tests should only have one reason to fail (again, the Single Responsibilty Principle, this thing is every-frikin’-where!), and doing networking introduces an extra factor for failure. Now a test ight fail because the production code is failing or because the rails server is down, or because the database is down, or because the office dog stepped over the router’s plug and disconnected it.

Oh, is that the bit about Dependency Injection?

Indeed, it is. Actually, it is more about Dependency Inversion, which happens to be the “D” in SOLID.

Depend upon abstractions, do not depend upon concretions.

Or quoting Napoleon and friends again:

Abstractions good, concretions bad!

In our previous example, List depends on a concretion: a specific instance of DefaultDataLoader. That deendency is hardcoded, and it can not be changed after compilation.

Let’s make List depend on an abstraction. One of the tools we have to model abstractions in Swift, line in many other languages, is protocols (interfaces).

So, let’s begin by defining a DataLoader protocol, by just extracting the public API of the DefaultDataLoader class:

1

2

3

4

5

6

7

8

9

protocolDataLoader{

func load(completion:([Item]?)->Void)

}

finalclassDefaultDataLoader:DataLoader{

func load(completion:([Item]?)->Void){

// Do whatever is necessary to fetch data from the backend

}

}

Now, we can inject that dependency into the List class:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

finalclassList{

let dataLoader:DataLoader

vardataSource:DataSource?

init(dataLoader:DataLoader){

self.dataLoader=dataLoader

}

overwrite func viewDidLoad(){

dataLoader.load(completion:dataReceived)

}

privatefunc dataReceived(data:[Item]?){

dataSource=DataSource(data:data)

tableView.dataSource=dataSource

}

}

Dependency Injection is a 20 dollar word for a 20 cent concept. I wish I had come up with that quote, but I didn’t.

But the point is that DI is as simple as that. If class A needs to use class B, pass to class A a reference to class B.

Why do we type it as an interface though? Well, because we want to rely on abstractions, not concretions, remember? And also, because…

Finally! Here comes the ta-dah!

Indeed it comes. The way List looks now, we would need to do somethign like this when initializing it:

1

2

let dataLoader=DefaultDataLoader()

let list=List(dataLoader:dataLoader)

Or if you have a thing for one liners:

1

let list=List(dataLoader:DefaultDataLoader())

Which is fine, but can become annoying if we only need to provide one concrete implementation of DataLoader. And also because, and we are splitting hairs here, that code could look cleaner and read simpler.

And, finally, this is where we get to discuss default values in parameters.

Let’s rewrite the List initializer like this:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

finalclassList{

let dataLoader:DataLoader

vardataSource:DataSource?

init(dataLoader:DataLoader=DefaultDataLoader()){

self.dataLoader=dataLoader

}

overwrite func viewDidLoad(){

dataLoader.load(completion:dataReceived)

}

privatefunc dataReceived(data:[Item]?){

dataSource=DataSource(data:data)

tableView.dataSource=dataSource

}

}

Now, to create an instance of List:

1

let list=List()

It literally, doesn’t get any simpler than that.

But the best is jet to come.

BYOM (Bring Your Own Mock)

Remember what we discussed about unit tests? Yes, unit tests should not hit the network, and we shoud be able to mock data fetched from the network.

Well, the thing is we can unit test List mocking data like this:

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

@testable import MyModule

import XCTest

finalclassMockLoader:DataLoader{

privatestructConstants{

staticlet unicorn=Item(id:"")

staticlet rainbow=Item(id:"")

}

func load(completion:([Item]?)->Void){

completion([Constants.unicorn,Constants.rainbow])

}

}

finalclassMediaUsedListTests:XCTestCase{

privatevarlist:List?

override func setUp(){

super.setUp()

list=MediaUsedList(dataLoader:MockLoader())

}

override func tearDown(){

list=nil

super.tearDown()

}

func testWhatNot(){

let something=list.whatever()

XCTAssertEqual(something,23)

}

}

This is Good, with a capital G, because we can provide List with whatever data set we need in order to tests its behaviour, without hitting the wire.