Quick example using classes and protocols in Swift.
I am a Java developer and not native to Objective-C.
I didn’t even spend a whole day learning Swift so everything stated here is probably wrong and not how Apple intended Swift to be used.
But it is how I intend to use it.
Composition over inheritance
Learning design patterns mostly boils down to accepting that inheritance is pretty useless and that almost all patterns are based on the mantra prefer composition over inheritance.
Done right this offers better:
- code reuse
- separation of concerns
So don’t be afraid to create many files, classes and interfaces.
Checking out Swift you can find all the ingredients required to build a nicely composed object (even more as we have extensions). But for now we need classes and protocols (basically interfaces in Apple talk).
To draw up a quick example let’s create some animals and give them abilities. Nicely re-usable abilities obviously, who wants to work more than he has to?
I chose the following animals:
Knowing dogs, birds and flying dogs, we require some barking, chirping, walking and flying. This is where the magic of composition comes into play as barking and flying is something that can be shared between animals but only has to be implemented onces.
- Dogs & FlyingDogs: Bark
- Birds & FlyingDogs: Fly
To make those abilities interchangeable and re-usable we need to create two protocols that define the abstract behaviour of making a sound and moving.
Those protocols are very simple and only define a method each returning a String.
Using that we can now look into some concrete implementations of those protocols.
Having the abilities covered we can create our animals. As each animal will be able to make a sound and move (plus being lazy) we start by creating an “abstract” animal that uses our protocols to do the actual sounding and moving. This way all “concrete” animals don’t have to do that work themselves.
As you can see the animal class can become any animal it likes to be by just switching abilities. Implementing a dog, bird and flying dog now becomes trivial.
By simply inheriting from animal we just have to override the default initialiser (constructor) of each animal and plug in the correct behaviours and pass it on to initialiser of our parent animal class.
Last thing to (well normally should be first thing) is to write some unit tests to actually verify that what we just did actually works.
We see that the dog barks, the bird flies and the flying dog barks and flies.