Wednesday, August 20, 2014

Design Patterns in Cocoa - How Much You Know ??

         In continuation to the articles on most frequently asked questions in an interview, I add another here which can be the most expected one to be asked. If you happen to fortunately survive any technical interview past 30-40 mins, you may notice that the topics on which the questions asked thereafter becomes generic and will be more of analogous in answers. Its the time for you to bring your understanding to wire and show your sense of application to your learnings to the problem on hand. So when the process of designing a solution to any software problem begins, thats when the understanding of Design Patterns do rise. "Any solution you design to solve a problem on hand is a Design Pattern" off course. Its quite obvious that the kind of design being adapted would be based on the kind of the problem to be solved.                   

        Cocoa architecture in itself has many Design Patterns implemented in any iOS project you create. So when you create an iOS project even beyond you knowing, there are many Design Patterns at work, making your life of application development easier. If so, lets know what are those design patterns implemented by Cocoa which you will have used for sure as an iOS developer, but may not be aware of.                  

        The first set of files which you start looking at in any iOS project is AppDelegate. This file has the methods needed to write in the logic for different states of app functioning like Foreground state, Background state, resigning active, becoming active etc. These things are quite evident and understandable, thanks to Apple standard of verbose naming convention of functions. But were you aware that AppDelegate is an example of "Singleton Pattern" of designing solution ? You might have noticed the practice of storing API Keys, Session Variables and other tokens in AppDelegate. But have you ever questioned why ? AppDelegate is a Single Shared instance that you access throughout the classes in your application and you dont ever do a "alloc" on it but rather use [UIApplication sharedApplication] which fetches back the shared singleton instance of reference. A single object created is shared throughout and is therefore called as Singleton Pattern.                

          Having started with AppDelegate and realising how Singleton Design pattern is in play with it, lets explore some other design patterns which come within. In the same AppDelegate class have you noticed that your class subclasses UIResponder  and implements a delegate by the name  <UIApplicationDelegate>. Take your time and explore UIApplicationDelegate and you will get to know that all the methods you have implemented in AppDelegate are prototyped in <UIApplicationDelegate>. This is called as "Delegation Pattern". A class delegating the responsibilities of it to a different one and make that delegate to conform back to it on task completion is called as Delegation. Where do you most get to see delegation and why ? What exactly is delegation ? In the MVC approach, a controller interacts with its view using delegation. A delegate always has a 1:1 relation with its view controller. But why does a delegate enforce 1:1 relation ? And if so why should delegation be used between a controller and a view ? A delegate appointed is always expected to report back to his master class and not others. A view element can always be tagged to a controller to drive it and cannot be shared by multiple controllers. For Ex : Screen A can always be tagged to Controller A and cannot be shared by Controller A and Controller B. This therefore enforces 1:1 relationship between a view and a controller and therefore they interact using delegation pattern.  Other popular examples of delegation pattern are UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate, UItextFieldDelegate, UIScrollViewDelegate etc.

      Most of you might be knowing that Objective C is a dynamic language. All it means is that the memory operations do happen at run time and the type of object and function linking is deferred to run time and doesnt happen at compile time. Now coming back to memory a bit, how do we allocate a block of memory for any object in objective c ? Its quite well know that all of us do use alloc method. Isnt it ? But do we know where is this method defined ? Do we know how does this method become available even with our custom classes without we doing anything ? Do we know how this method is internally implemented ? Ooopss.. Lets stop questions for a while here and start answering them. alloc is called as a factory method and is an example of "Factory Design Pattern". alloc is defined as a part of the NSObject class which is the root class of all objective c classes.  Most of the classes in objective C act as interfaces for a cluster of classes which sub-class the interface and are called as "Class Clusters". When alloc is called on any class, NSObject acts as a factory which manufactures an object and returns a reference to it using a suitable subclass of it from class cluster. In reference to this, most of you might have seen that when working with NSArray your program might crash giving an error with __NSArrayI or __NSArrayM. Have you ever given a thought as why did your program crash or did give error with these classes as references whereas you used NSArray ? Now go back few lines and relate it to the explanation there. NSArray is a public superclass of a cluster of classes which include __NSArrayI or __NSArrayM. NSArray just acts as a factory which returns the object reference when called upon alloc with it, hiding the implementation details underneath. When will __NSArrayI be used or when will __NSArrayM be used will be discussed in a different post "Class Clustering". So do you now realise how frequently and efficiently has Factory Design Pattern been used in all the frameworks of iOS and you also had used it in all your programs but you never knew about it ??!!

      
        In most of the cases we might have used notification centres to broadcast a notification using the default centre and thereby inform all the observers of a particular change. As soon as the word broadcast strikes your mind, it should even strike you that this follows 1:n relationship and not 1:1 unlike delegates which we saw a few paragraphs above. If so, lets see of what significance can these be and how better can we use them in our coding. Whenever an object wants to broadcast a message to all other objects in the eco-system which are interested in it, then it broadcasts a notification. All the objects which are interested in listening to this notification will register themselves as an observer to these changes. Lets see it in action. Now lets assume that a row of an employee table was being deleted and this has to be notified to n classes which have to perform actions accordingly. All these classes which are supposed to act onto the deletion that happens on employee table record register themselves as observers to the "delete" event happening on employee table object. Now as and when the deletion happens and the table object broadcasts a deletion notification using the notification center all these classes perform associated actions. This is called as "Observer Design Pattern". Most of you might have used this for keyboard appearing notification on beginning to edit a text field so as to adjust your layout. As we did see that a controller coordinates with the view using delegation pattern, a modal coordinates with controller using observer pattern. A modal which might be a table in the database might be used across multiple controllers unlike views which were tagged to a controller. Therefore modals will have to signal a change on them to all the controllers which they are associated with and thereby Observer Design Pattern comes in handy.

          Whenever you try to add a new class to Xcode project you are forced to select a superclass of that which has to be either a View or a Controller or a Modal(NSObject). Do You know by default you are following "MVC Design Pattern" here ? Now lets quickly see what MVC pattern is and why it is the most emphasised of all for designing the architecture of the project. Modal - An object in which the data resides V - A view element to represent the data residing in the Modal object C - Driver which maps elements of V with M. This is as simple as it is. Properly structuring an application to have easy mapping and storage of data on to the view is all about MVC.Now lets see how does this help. When we have a proper MVC architecture followed we thereby ensure that no data(Modal) is tightly coupled with a View and hence the same data object can be used across views. For example : Lets assume the details of an employee are to be shown in 2 different screens in a different layout. If we follow MVC, we ensure that employee data object is nowhere tightly coupled with any of the two screens which need to render it in a layout of their own and thereby we can reuse the same object in both the screens. Both the screens will have their own controllers to interact with the same employee modal object to coordinate with. This thereby ensures re-usability, better modularisation and as the objects are loosely coupled, changes such as adding a field to the table ot removing a field from the table does not demand significant rework. 


         These are some of the Design Patterns which are quite extensively used in Objective C and the list keeps growing for the enthusiasts. Any problem at hand can be easily solved by understanding how the solution can be approached using a design pattern. The best part is that all these design patterns can be blended with each other, each one implemented for a feature that best suits them and thereby architecture the design of application in a much easier way. Now I guess you are proud to have used so many Design Patterns in every application of yours in Objective C even though you never might have designed them on your own :) 






2 comments:

  1. It is very interesting read. Keeping it up.

    ReplyDelete
  2. Great article. Enlightening when it comes to the alloc method and how it implements the factory design pattern.

    ReplyDelete