iOS Mobile Architecture — Part One
What is Architecture?
Developers use software architecture to set out the patterns an application should be built upon, the overall structure of the project, how objects are created and relationships between objects are made and maintainted.
But why is this important?
Software architecture is important as it constrains developers to use a certain pattern and structure within their code to ensure the following:
- Code is clean, modular and therefore reusable
- The concerns of objects are separated, this ensures that we don’t end up with a “God Class” that does everything.
- Change to requirements can be fulfilled quickly in fewer places, allowing for faster development.
The list goes on and on, but trust me… good architecture will save you time!
What Architecture would I recommend?
I have come up with a very simple architecture that has made my time developing features and entire projects far easier, it’s a take on the MVP pattern.
How does it work?
Here’s a quick bullet point overview of how it works.
- Code is split up into more files, smaller files!
- Write all code to interfaces to allow for quick change and to make code more testable.
- Dependency Injection is used, it’s not as scary as it sounds! — Just pass dependencies into the constructor, fairly simple.
- ViewControllers only do what the same suggests, they control views. All other functionality is delegated to another object. No more api calls and data manipulation in ViewControllers! No navigation in ViewControllers either.
- Controllers (.NET guys/girls will know these as services) are used to do the heavily lifting. e.g. a UserController to handle user data.
- An AppContainer will be created to hold the single strong reference to Controllers and inject them where needed. NO MORE STATIC SINGLETONS — Seriously, if you want testable code then leave these alone.
- We’ll need to set out the flow of the app so we’ll create Directors to handle this for us e.g. an EntryDirector will figure out if we take the user to the login screen or straight into the app.
If you enjoyed this short article then leave me some feedback, if it gets enough interest then i’ll write another on how to actually implement this pattern.
Good article!
I want to discuss 3 things.
Why do you think is good to create protocol/interfaces for everything? Will it not create maintenance overhead?
And for some few cases inheritance is favourable.
I also think we dont always need protocol to make test code easier, you can always subclass the dependency. What do you think of this?
You mention vc should not handle navigation. Where would you place them?
Hi Adi,
In my experience creating interfaces for everything (apart from core data entities) does not create extra maintenance as the interface is used instead of the .h file to add all public methods and properties. So this is still only changed in one place.
Inheritance is certainly favourable is some areas to keep things SOLID. Can’t agree more.
Protocols/interfaces certainly do make testing easier in most cases as you can mock items (I use OCMock) based on the interface rather than the class concretion, that makes tests and the code in general less brittle and more loosely couples.
The VC not handling navigation is a good question. In the article above I mention directors, in my architecture these handle navigation. So a LoginViewController would have the EntryDirector as it’s delegate. Let’s say for example the user taps ‘Forgot Password’ on the LoginViewController. The VC would then call [self.delegate userTappedForgotPassword]; (the delegate being the EntryDirector). The entry director would then instantiate the ForgotPasswordViewController and push it onto the navigation controller.