0% found this document useful (0 votes)
46 views41 pages

Objective C Design Patters1

This document discusses Objective-C design patterns, including programming to interfaces, object composition vs class inheritance, and class clusters. It explains that class clusters use an abstract superclass to simplify public classes while hiding concrete subclasses. Class clusters provide factory methods to allocate the proper subclass instance based on the creation method used. This allows polymorphism while hiding implementation details.

Uploaded by

Ashar Kizaki
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views41 pages

Objective C Design Patters1

This document discusses Objective-C design patterns, including programming to interfaces, object composition vs class inheritance, and class clusters. It explains that class clusters use an abstract superclass to simplify public classes while hiding concrete subclasses. Class clusters provide factory methods to allocate the proper subclass instance based on the creation method used. This allows polymorphism while hiding implementation details.

Uploaded by

Ashar Kizaki
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 41

Objective C Design Patters

Asfar
Design Principles
Programming To An Interface, Not An
Implementation
Define classes with identical interfaces is important because
polymorphism depends on the interfaces.
In Objective-C, protocol acts like a contract of objects. Implementing a
protocol or inheriting from an abstract class let objects share the same
interfaces
So all objects of the subtypes can respond to the requests in the interface
of the protocol or abstract class.
There are two benefits from the practice:
As long as the objects conform to the interface that clients expect, the clients
shouldnt be aware of the exact types of objects they use.
Clients only know about the protocol(s) or abstract class(es) defining the
interface, so the clients dont know anything about the objects classes.
This leads to the principle of reusable object-oriented software design
according to the Gang of Four book:
Program to an interface, not an implementation.
A common practice in client code is not to declare variables of particular
concrete classes objects. Instead, use only an interface defined by a
protocol or an abstract class.
Object Composition vs. Class Inheritance
Class inheritance or subclassing allows you to define an
implementation of a class in terms of anothers.
Subclassing is often referred to as white-box reuse because the
internal representation and details of parent classes are often
visible to subclasses.
Object composition is an alternative to class inheritance.
Object composition requires that the objects being composed
have well-defined interfaces and that they are defined
dynamically at runtime through references acquired by other
objects.
So you can compose objects within other ones to create more
complex functionality.
Since no internal details of objects are visible to others, they
appear as black boxes and this style of reuse is called black-
box reuse.
class inheritance
Pros:
Class inheritance is straightforward to use because the relationship is defined
statically at compile-time.
It makes it easier to modify the implementation being reused.
Cons:
Because class inheritance is defined at compile-time, you cant change the
inherited implementations from parent classes at runtime.
Part of the representation in subclasses is often defined in parent classes.
Subclasses are exposed to details of parent classes implementation, so it breaks
encapsulation.
Any change in the parents implementation will force its subclasses to change as
well because their implementations are so tied up together.
You need to rewrite the parent class or the inherited implementation because the
inherited implementation becomes obsolete or inappropriate for new problem
contexts.
Reusing a subclass can be problematic due implementation dependencies. One
solution for this is to inherit (subtype) only from protocol(s) or abstract (base)
class(es), as they usually have little or, in a protocol, no implementation.
Object Composition
Pros:
You dont break encapsulation because objects are now accessed only through
their interfaces.
There are substantially fewer implementation dependencies, as the objects
implementation is defined in terms of the interfaces.
You can replace any object at runtime with another of the same type.
It helps keep a class encapsulated so it can focus on one task.
Your classes and their hierarchies will remain small. They will be less likely to grow
into something unmanageable.
Cons:
The design will tend to have more objects.
The behavior of the system will depend on the relationships of different objects
instead of being defined in one class.
Ideally, there is no need to create new components to achieve reuse. It is quite
rare that you should be able to get all the functionality you need just by
assembling existing components through object composition. In practice, the set
of available components is never quite rich enough.
Despites the cons, object composition can provide many benefits on system design.
Those cons can be counter-balanced by using class inheritance in certain areas as it
helps make it easier to make new components from old ones.
favor object composition over class
inheritance
It doesnt mean that you shouldnt use class
inheritance at all. You need to make a clear
judgment on how to reuse classes and objects
in certain situations.
Class inheritance and object composition can
work together if you design them properly for
your systems.
You will see object composition in the design
patterns discussed later.
Design Patterns
Class Clusters -- Abstract Factory
An abstract superclass is declared with
methods that are implemented in nonvisible,
concrete subclasses.
Simplify the complexity of public classes by
revealing only the methods declared in the
abstract parent class.
The abstract superclass is responsible for
providing methods that create instances of
the private subclasses.
Why use class clusters
Two common motivations for taking this design approach:
Performance/Memory
This type of design allows a developer to make a single class that can represent the
creation point for multiple objects that have significantly different memory
requirements.
The classic example of this is the NSNumber class.
NSNumber is a cluster representing all sorts of different number types (Integer, Double,
Long, Float, Char). All of these types can be converted from one to another, and all
share many different methods that act on them. But they all require different amounts
of memory. Therefore, Apple made NSNumber the cluster that handles the
management of all the hidden subclasses that handle the different types.
Simplicity
Creating a class cluster can simplify the interface to a collection of similar classes.
All the different objects contained in NSNumber would be very unwieldy to develop
without the NSNumber wrapper. Operations such as conversion, or arithmetic
operations like division would require developers to be very careful about memory
management. NSNumber, however, shifts this responsibility from the developer to the
class cluster, greatly simplifying the use of these similar classes.
Number Cluster
Number is the abstract superclass that declares in its methods the
operations common to its subclasses. However, it doesnt declare an
instance variable to store a number.
The subclasses declare such instance variables and share in the
programmatic interface declared by Number.
private classes are in gray
Creating Instances
Users of this hierarchy see only the public class, Number, so
how is it possible to allocate instances of the proper
subclass?
The abstract superclass in a class cluster must declare
methods for creating instances of its private subclasses.
Its the superclasss responsibility to dispense an object of
the proper subclass based on the creation method that
you invokeyou cant choose the class of the instance.
In the Foundation framework, you generally create an
object by invoking a +className ... method or the
alloc... and init... methods.
NSNumber example
Foundation frameworks NSNumber class provides these messages
to create number objects:
NSNumber *aChar = [NSNumber numberWithChar:a];
NSNumber *anInt = [NSNumber numberWithInt:1];
NSNumber *aFloat = [NSNumber numberWithFloat:1.0];
NSNumber *aDouble = [NSNumber numberWithDouble:1.0];
Each object returnedaChar, anInt, aFloat, and aDouble - belong to a
different private subclass.
Although each objects class membership is hidden, its interface is
public, being the interface declared by the abstract superclass,
NSNumber.
Although it is not precisely correct, its convenient to consider the
aChar, anInt, aFloat, and aDouble objects to be instances of the NSNumber
class, because theyre created by NSNumber class methods and
accessed through instance methods declared by NSNumber.
Class Clusters with Multiple Public Superclasses
Its also possible, to have two (or possibly more) abstract public classes
that declare the interface for the cluster

Class cluster Public superclasses

NSData
NSData
NSMutableData
NSArray
NSArray
NSMutableArray
NSDictionary
NSDictionary
NSMutableDictionary
NSString
NSString
NSMutableString
In each of these clusters, one public node declares methods
that all cluster objects can respond to, and the other node
declares methods that are only appropriate for cluster
objects that allow their contents to be modified.
This factoring of the clusters interface helps make the
interface more expressive.
For example, imagine an object representing a book that
declares this method:
- (NSString *)title;
The book object could return its own instance variable or create
a new string object and return thatit doesnt matter. Its clear
from this declaration that the returned string cant be modified.
Any attempt to modify the returned object will elicit a compiler
warning.
Class Factory Methods
Class factory methods are implemented by a class
as a convenience for clients. They combine
allocation and initialization in one step and return
the created object.
The client receiving this object does not own the
object and thus (per the object-ownership policy)
is not responsible for releasing it.
These methods are of the form + (type
)className ... (where className excludes any
prefix).
NSDate/ NSData class factory
methods:
+ (id)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs;
+ (id)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secs;
+ (id)dateWithTimeIntervalSince1970:(NSTimeInterval)secs;

NSData :
+ (id)dataWithBytes:(const void *)bytes length:(unsigned)length;
+ (id)dataWithBytesNoCopy:(void *)bytes length:(unsigned)length;
+ (id)dataWithBytesNoCopy:(void *)bytes length:(unsigned)length
freeWhenDone:(BOOL)b;
+ (id)dataWithContentsOfFile:(NSString *)path;
+ (id)dataWithContentsOfURL:(NSURL *)url;
+ (id)dataWithContentsOfMappedFile:(NSString *)path;
Uses
The allocation can inform the initialization.
As an example, lets say you must initialize a collection object from a
property-list file that encodes any number of elements for the collection
(NSString objects, NSData objects, NSNumber objects, and so on).
Before the factory method can know how much memory to allocate for the
collection, it must read the file and parse the property list to determine how
many elements there are and what object type these elements are.
Implementation of singleton classes.
Although an init... method could verify that only one instance exists at any one
time in a program, it would require the prior allocation of a raw instance
and then, in memory-managed code, would have to release that instance. A
factory method, gives you a way to avoid allocating memory for an object that
you might not use:

static AccountManager *DefaultManager = nil;


+ (AccountManager *)defaultManager {
if (!DefaultManager) DefaultManager = [[self allocWithZone:NULL] init];
return DefaultManager;
}
Delegates
A delegate is an object that acts on behalf of,
or in coordination with, another object when
that object encounters an event in a program.
The delegating class has an outlet or property,
usually one that is named delegate;
if it is an outlet, it includes methods for setting
and accessing the value of the outlet.
It also declares, without implementing, one or
more methods that constitute a protocol.
The mechanism of delegation
Example
when a user clicks the close button of a window
in OS X, the window object sends the
windowShouldClose: message to its delegate; this
gives the delegate the opportunity to veto or
defer the closing of the window if, for example,
the window has associated data that must be
saved
The delegating object sends a message only if the
delegate implements the method. It makes this
discovery by invoking the NSObjectmethod
respondsToSelector: in the delegate first.
Delegation principle
Allow one object to define some subset of the
behavior of another object.
Its very common in UIKit.
Each user interface object uses delegation to allow
you to define what happens in response to user
interface events.
Related to general rule that favor object
composition over inheritance.
This is important for loose coupling which makes
it much easier to reuse the code.
The Form of Delegation Methods
They begin with the name of the UIKit object doing the
delegatingapplication, window, control, and so on; this
name is in lower-case and without the UI prefix.
Usually (but not always) this object name is followed by
an auxiliary verb indicative of the temporal status of the
reported event.
This verb, in other words, indicates whether the event is
about to occur (Should or Will) or whether it has just
occurred (Did or Has).
This temporal distinction helps to categorize those
messages that expect a return value and those that
dont.
Will/should
UIApplicationDelegate
-(BOOL)application:(UIApplication *)application
handleOpenURL:(NSURL *)url;
UITableViewDelegate
- (UITableRowIndexSet *)tableView:(NSTableView *)tableView
willSelectRows:(UITableRowIndexSet *)selection;
The delegate that implements these methods can block the
impending event (by returning NO in the first method) or
alter a suggested value (the index set in the last method).
It can even defer an impending event; for example, the
delegate implementing the applicationShouldTerminate:method
can delay application termination by returning
NSTerminateLater.
Informational delegate methods
Other delegation methods are invoked by messages that dont expect a
return value and so are typed to return void. These messages are purely
informational, and the method names often contain Did, Will, or some
other indication of a transpired or impending event.
NSWindow - (void)windowDidMove:(NSNotification *)notification;
NSApplication -(void)applicationWillBecomeActive:(NSNotification
*)notification;
An auxiliary verb of Will does not necessarily mean that a return value is
expected. In this case, the event is imminent and cannot be blocked, but
the message gives the delegate an opportunity to prepare the program for
the event.
The last method is invoked as the result of the posting of a particular
notification. The delegating object automatically makes its delegate an
observer of all notifications it posts. All the delegate needs to do is
implement the associated method to get the notification.
UIKit
The UIKit framework uses delegation extensively and
always implements it using protocols.
The application delegate is extremely important in an
application running in iOS because it must respond to
application-launch, application-quit, low-memory, and
other messages from the application object.
The application delegate must adopt the
UIApplicationDelegate protocol.
Delegating objects do not (and should not) retain their
delegates. However, clients of delegating objects
(applications, usually) are responsible for ensuring that
their delegates are around to receive delegation messages.
Becoming the Delegate of a
Framework Class
A framework class or any other class that implements delegation
declares a delegate property and a protocol . The protocol lists the
required and optional methods that the delegate implements.
For an instance of your class to function as the delegate of a
framework object, it must do the following:
Set your object as the delegate (by assigning it to the delegate
property). You can do this programmatically or through Interface
Builder.
If the protocol is formal, declare that your class adopts the protocol in
the class definition. For example:
@interface MyControllerClass : UIViewController <UIAlertViewDelegate> {
Implement all required methods of the protocol and any optional
methods that you want to participate in.
Data Sources
A data source is like a delegate except that, instead of being delegated
control of the user interface, it is delegated control of data.
A data source is an outlet held by UIView objects such as table views and
outline views that require a source from which to populate their rows of
visible data.
The data source for a view can be the delegate object or any other object.
As with the delegate, the data source must implement one or more
methods of protocol to supply the view with the data it needs.
Data sources are responsible for the persistence of the objects they hand
out to user-interface objects. In other words, they are responsible for the
memory management of those objects.
Whenever a view object such as an outline view or table view accesses the
data from a data source, it retains the objects as long as it uses the data.
Typically it holds on to the data only long enough to display it.
Model-View-Controller (MVC)
It is a high-level pattern.
It concerns itself with the global architecture of an
application and classifies objects according to the general
roles they play in an application.
It is also a compound pattern
It comprises several, more elemental patterns.
Many objects in these programs tend to be more
reusable and their interfaces tend to be better defined.
The programs overall are more adaptable to changing
requirements.
They are more easily extensible than programs that are
not based on MVC.
Roles and Relationships of MVC
Objects
The MVC design pattern considers there to be three types of
objects:
model objects,
view objects,
controller objects.
The MVC pattern defines the roles that these types of objects play
in the application and their lines of communication.
When designing an application, a major step is choosingor
creating custom classes forobjects that fall into one of these
three groups.
Each of the three types of objects is separated from the others by
abstract boundaries and communicates with objects of the other
types across those boundaries.
Traditional version of MVC as a
compound pattern
Model Objects Encapsulate Data and
Basic Behaviors
Model objects represent special knowledge and expertise. They hold an
applications data and define the logic that manipulates that data.
A well-designed MVC application has all its important data encapsulated
in model objects.
Any data that is part of the persistent state of the application (whether
that persistent state is stored in files or databases) should reside in the
model objects once the data is loaded into the application.
Because they represent knowledge and expertise related to a specific
problem domain, they tend to be reusable.
Ideally, a model object has no explicit connection to the user interface
used to present and edit it.
For example, if you have a model object that represents a person (say you
are writing an address book), you might want to store a birthdate. Thats a
good thing to store in your Person model object. However, storing a date
format string or other information on how that date is to be presented is
probably better off somewhere else.
View Objects Present Information to the User
A view object knows how to display, and might allow users to edit, the
data from the applications model.
The view should not be responsible for storing the data it is displaying. (A
view can cache data or do similar tricks for performance reasons).
A view object can be in charge of displaying just one part of a model
object, or a whole model object, or even many different model objects.
Views come in many different varieties.
View objects tend to be reusable and configurable, and they provide
consistency between applications.
UIKit framework defines a large number of view objects and provides
many of them in the Interface Builder library. By reusing view objects, such
as UIButton objects, you guarantee that buttons in your application
behave just like buttons in any other application, assuring a high level of
consistency in appearance and behavior across applications.
A view should ensure it is displaying the model correctly. Consequently, it
usually needs to know about changes to the model. Because model
objects should not be tied to specific view objects, they need a generic
way of indicating that they have changed.
Controller Objects Tie the Model to the View
A controller object acts as the intermediary between the application's view objects
and its model objects.
Controllers are often in charge of making sure the views have access to the model
objects they need to display and act as the conduit through which views learn
about changes to the model.
Controller objects can also perform set-up and coordinating tasks for an
application and manage the life cycles of other objects.
In a typical Cocoa MVC design, when users enter a value or indicate a choice
through a view object, that value or choice is communicated to a controller object.
The controller object might interpret the user input in some application-specific way and
then either may tell a model object what to do with this input
for example, "add a new value" or "delete the current record"or it may have the
model object reflect a changed value in one of its properties.
Based on this same user input, some controller objects might also tell a view object to
change an aspect of its appearance or behavior, such as telling a button to disable itself.
Conversely, when a model object changessay, a new data source is accessedthe
model object usually communicates that change to a controller object, which then
requests one or more view objects to update themselves accordingly.
Combining Roles
One can merge the MVC roles played by an object, making an object, for
example, fulfill both the controller and view rolesin which case, it would
be called a view controller .
In the same way, you can also have model-controller objects. For some
applications, combining roles like this is an acceptable design.
A model controller is a controller that concerns itself mostly with the
model layer. It owns the model; its primary responsibilities are to
manage the model and communicate with view objects.
Action methods that apply to the model as a whole are typically
implemented in a model controller. The document architecture provides a
number of these methods for you; for example, an NSDocument object
(which is a central part of the document architecture) automatically
handles action methods related to saving files.
A view controller is a controller that concerns itself mostly with the view
layer. It owns the interface (the views); its primary responsibilities are to
manage the interface and communicate with the model. Action methods
concerned with data displayed in a view are typically implemented in a
view controller. An NSWindowController object (also part of the document
architecture) is an example of a view controller.
MVC as a Compound Design Pattern
Model-View-Controller is a design pattern that is composed of several
more basic design patterns.
These basic patterns work together to define the functional separation
and paths of communication that are characteristic of an MVC
application.
Traditional notion of MVC assigns a set of basic patterns different from
those that Cocoa assigns. The difference primarily lies in the roles given to
the controller and view objects of an application.
Traditional MVC
In the original (Smalltalk) conception, MVC is made up of the Composite,
Strategy, and Observer patterns.
CompositeThe view objects in an application are actually a
composite of nested views that work together in a coordinated fashion
(that is, the view hierarchy). These display components range from a
window to compound views, such as a table view, to individual views,
such as buttons. User input and display can take place at any level of
the composite structure.
StrategyA controller object implements the strategy for one or more
view objects. The view object confines itself to maintaining its visual
aspects, and it delegates to the controller all decisions about the
application-specific meaning of the interface behavior.
ObserverA model object keeps interested objects in an application
usually view objectsadvised of changes in its state.
Cocoa MVC
Object Mutability
Cocoa objects are either mutable or
immutable.
You cannot change the encapsulated values of
immutable objects. Once such an object is
created, the value it represents remains the
same throughout the objects life.
You can change the encapsulated value of a
mutable object at any time.

You might also like