Design Patterns on iOS

Adapter, Chain of responsibility, Decorator, Facade, iOS design patterns, iOS Architecture Patterns, Cocoa Design Patterns, iOS pattern
In this article, i am going to cover four design patterns which you can relate with your current project and its easy to understand with examples like how cocoa adapts those patterns. Let’s start…

Design Patterns iOS

Adapter, Chain of responsibility, Decorator, Facade

In this article, i am going to cover four design patterns which you can relate with your current project and its easy to understand with examples like how cocoa adapts those patterns. Let’s start with adapter..

1. Adapter

The Adapter design pattern converts the interface of a class into another interface that clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. It decouples the client from the class of the targeted object.

How Cocoa adapts Adapter Design Patterns?

Protocols

A protocol is a language-level (Objective-C) feature that makes it possible to define interfaces that are instances of the Adapter pattern. A protocol is essentially a series of method declarations unassociated with a class. (In Java, interface is synonymous with protocol.) If you want a client object to communicate with another object, but the objects’ incompatible interfaces make that difficult, you can define a protocol. The class of the other object then formally adopts the protocol and “conforms” to it by implementing one or more of the methods of the protocol. The protocol may require the conforming class to implement some of its methods and may leave the implementation of others optional. The client object can then send messages to the other object through the protocol interface.

Note: Design of protocols does not perfectly match the description of the Adapter pattern. But it achieves the goal of the pattern: allowing classes with otherwise incompatible interfaces to work together.

Uses and Limitations

For example, the Foundation framework includes the NSObject, NSCopying, and NSCoding protocols, which are all very important ones. AppKit protocols include NSDraggingInfo, NSTextInput, and NSChangeSpelling. UIKit protocols include UITextInputTraits, UIWebViewDelegate, and UITableViewDataSource.

2. Chain of Responsibility

The Chain of Responsibility design pattern decouples the sender of a request from its receiver by giving more than one object a chance to handle the request. The pattern chains the receiving objects together and passes the request along the chain until an object handles it. Each object in the chain either handles the request or passes it to the next object in the chain.

How Cocoa adapts Chain of Responsibility Design Patterns?

Responder Chain

The application frameworks include an architecture known as the responder chain. This chain consists of a series of responder objects (that is, objects inheriting from NSResponder or, in UIKit, UIResponder) along which an event (for example, a mouse click) or action message is passed and (usually) eventually handled. If a given responder object doesn’t handle a particular message, it passes the message to the next responder in the chain. The order of responder objects in the chain is generally determined by the view hierarchy, with the progression from lower-level to higher-level responders in the hierarchy, culminating in the window object that manages the view hierarchy, the delegate of the window object, or the global application object. The paths of events and action messages up the responder chain is different. An application can have as many responder chains as it has windows (or even local hierarchies of views); but only one responder chain can be active at a time—the one associated with the currently active window.

Note: The design of the view hierarchy, which is closely related to the responder chain, adapts the Composite pattern.

Chain of responsibility example

Uses and Limitations

When you construct a user interface for a program either by using Interface Builder or programmatically, you get one or more responder chains “for free.” The responder chain goes hand in hand with a view hierarchy, which you get automatically when you make a view object a subview of a window’s content view. If you have a custom view added to a view hierarchy, it becomes part of the responder chain. If you implement the appropriate NSResponder or UIResponder methods, you can receive and handle events and action messages. A custom object that is a delegate of a window object or the global application object (NSApp in AppKit) can also receive and handle those messages.

3. Decorator

The Decorator design pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. As does subclassing, adaptation of the Decorator pattern allows you to incorporate new behavior without modifying existing code. Decorators wrap an object of the class whose behavior they extend. They implement the same interface as the object they wrap and add their own behavior either before or after delegating a task to the wrapped object. The Decorator pattern expresses the design principle that classes should be open to extension but closed to modification.

How Cocoa adapts Decorator Design Patterns?

Delegation

Delegation is a mechanism by which a host object embeds a weak reference (weak in the sense that it’s a simple pointer reference, unretained) to another object — its delegate — and periodically sends messages to the delegate when it requires its input for a task. The host object is generally an “off-the-shelf” framework object (such as an NSWindow or NSXMLParser object) that is seeking to accomplish something, but can only do so in a generic fashion. The delegate, which is almost always an instance of a custom class, acts in coordination with the host object, supplying program-specific behavior at certain points in the task (see Figure 1). Thus delegation makes it possible to modify or extend the behavior of another object without the need for subclassing.

Figure 1 Framework object sending a message to its delegate

Cocoa uses the Decorator pattern in the implementation of several of its classes, including NSAttributedString, NSScrollView, and UIDatePicker. The latter two classes are examples of compound views, which group together simple objects of other view classes and coordinate their interaction.

Uses and Limitations

Delegation is a common design in the Cocoa frameworks. Many classes in the AppKit and UIKit frameworks send messages to delegates, including NSApplication, UIApplication, UITableView, and several subclasses of NSView. Some classes in the Foundation framework, such as NSXMLParser and NSStream, also maintain delegates. You should always use a class’s delegation mechanism instead of subclassing the class, unless the delegation methods do not allow you to accomplish your goal.

Although you can dynamically change the delegate, only one object can be a delegate at a time. Thus if you want multiple objects to be informed of a particular program event at the same time, you cannot use delegation.

4. Facade

The Facade design pattern provides a unified interface to a set of interfaces in a subsystem. The pattern defines a higher-level interface that makes the subsystem easier to use by reducing complexity and hiding the communication and dependencies between subsystems.

How Cocoa adapts Facade Design Patterns?

NSImage

The NSImage class of the AppKit framework provides a unified interface for loading and using images that can be bitmap-based (such as those in JPEG, PNG, or TIFF format) or vector-based (such as those in EPS or PDF format). NSImage can keep more than one representation of the same image; each representation is a kind of NSImageRep object. NSImage automates the choice of the representation that is appropriate for a particular type of data and for a given display device. It also hides the details of image manipulation and selection so that the client can use many different underlying representations interchangeably.

Uses and Limitations

Because NSImage supports several different representations of what an image is, some requested attributes might not apply. For example, asking an image for the color of a pixel does not work if the underlying image representation is vector-based and device-independent.