Q) What is Architecture?
Architecting is nothing but organizing all, the independently working, layers in a best way that suits your project.
There is no one fixed architecture that suits well for all the projects all the time. Each projects could have an unique approach.
Now that being said, it would introduce two questions to you,
- What are independently working layers
- What do I mean by ‘suits your project’
What are ‘Independently Working Layers’
This is a single or set of class/structure/protocols, basically code, that serves a specific purpose in project. Network Manager, Services Classes, Presentation Layer Class(View Controllers & Views) are good examples. For example Network Manager and related files serves for only one purpose, that is, to handle network calls between server and client. This Network Manager should be working irrespective of what project it is, it can be plugged into some other projects as well.
What is mean by ‘suits your project’
Basically ‘suits your project’ is mean by ‘how data is passed between each layers of your project, from network manager to view controllers to views’.
Let me give you an example,
Let say the user is successfully logged in your app, you may need to fetch the user’s profile information from your REST API. You call the REST API and get back raw json object. Now that you have the raw json, you need to persist that data to your Core Data and get it back as a model object. Then the model object can be used by your view controllers to display.
Let me list out the layers involved in the single process,
- Views: To display data physically and user interaction.
- View Controller: To manage views and models.
- View Model: To do all non-UI related operation of a View Controller.
- Data Manager: To persist your data to core data/sqlite/anything (we need not have call this as a separate layer, we could call it as a component).
- Service: The place where the network request/calls are constructed and initiated.
- Network Manager: The place where the actual network calls occurs.
The catch here is each layer can only talk to one layer below or above, not more than that. Example, View can talk to view controller but it definitely shouldn’t talk to Service Layer. Each layer does a specific task in your project and it should definitely do only that.
Here is the diagram,
All the layers are stacked one above the other. Meaning each layer can only communicate with the layer, one level, above or below.
I don’t think we need an explanation for this. These are just views, where user can see and interact. In this layer you don’t have to do lot of work other than creating a clean and good UI & UX.
The general mistakes I have seen(and I have done in the past ;P) in many projects is that, letting your views communicate with your Model.
Let me give you an obvious example here,
Here, FriendTableViewCell is a view and we are passing the Friend model object inside. So we are letting the cell extract information from our model object. This definitely is breaking the MVC pattern.
Here is how we should be writing,
View controller is an important entity, it is where everything starts. It communicates with Views, Model Objects and View Models. Also optionally, some times, it communicates with Service Layer and Data Manager.
I recommend, always engage the view controller’s communication only with View Models. One of the main reasons is, if you interact with multiple layers, all your functionalities will be scattered around the entire place. It will make your debugging process hard and it makes the flow ugly. In my projects almost all view controllers will be backed by a separate view model.
There is no clear definition for view model so far, everyone has their own opinion on the concept of view model. I use view models to dump all the non-UI functionalities of a view controller or a particular module of my project. This strategy helps Unit Test the functionality of any view controllers.
List of things View Model could do,
- Communicate with appropriate Service Class
- Communicate with Data Manager to save or retrieve data
- Maintain controllers state. For example if user is filling a form, View Model can keep the all the filled form data.
- Perform operation on view controllers data.
- Parsing JSON object into your Model object.
Service classes reside just above the Networking Layer, because your project specific API calls are handled here.
We could have a service class called UserService, this class knows how to compose user profile relate API requests and also knows how to interpret responses. When I say ‘interpret responses’, it means not only the knowledge of reading success responses, but also the knowledge of error responses(error codes & error responses). So UserService is a complete package of profile related API calls.
Note: Service layer compose the network requests and hand over that request to Network Layer to take care of physical API calls.
Network Layer is a general purpose component, which performs your physical API calls. It deals with underlying classes like NSURLRequest, NSURLSession, NSURLConnection and NSOperationQueue.
Basically your Network layer knows nothing about your project and your server response. All it does is manage the underling network calls and give back the server responses.