Cocoa Design Patterns Pavel Kravchenko, Ciklum
What is a Design Pattern? A design pattern is: a template for a design that solves a general problem a tool of abstraction that is useful in architecture A vocabulary to use when explaining complex software
Design principles encapsulate the aspects of system structure program to an interface, not an implementation Minimize coupling
The Command encapsulate a request as an object and  Separates message sender and reciever
The Command
The Command Use when you want to: parameterize objects by an action to perform (Commands are an object-oriented replacement for callbacks). specify and execute requests at different times (you can transfer a command object to a different process). support undo.  support logging changes.
The Command Example: NSInvocation (encapsulates an Objective-C message) An invocation object contains a target object, method selector, and method arguments You can dynamically change its target and arguments you can also obtain the return value from the object you can repeatedly invoke a message with multiple variations in target and arguments
Abstract Factory Provide an interface for creating families of related or dependent objects without specifying their concrete classes. The client is decoupled from any of the specifics of the concrete object obtained from the factory.
Abstract Factory
Abstract Factory Use the Abstract Factory pattern when: • a system should be independent of how its products are created and represented. • a system should be configured with one of multiple families of products.  • a family of related product objects is designed to be used together
Class cluster A class cluster is an architecture that  groups a number of private, concrete subclasses under an abstract superclass. The abstract superclass declares methods for creating instances of its private subclasses.  Each object returned may belong to a different private concrete subclass. you don’t, and can’t, choose the class of the instance.
Class cluster NSNumber *aChar = [NSNumber numberWithChar:’a’]; NSNumber *anInt = [NSNumber numberWithInt:1]; NSNumber *aFloat = [NSNumber numberWithFloat:1.0]; NSNumber *aDouble = [NSNumber numberWithDouble:1.0];
Class cluster Since numbers of different types can be converted from one type to another and can be represented as strings, for example, they could be represented by a single class. aChar ,  anInt ,  aFloat ,  aDouble —are objects of different private subclasses but them interfaces declared by the NSNumber Don't release objects returned from factory methods
Chain of Responsibility Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.  Chain the receiving objects and pass the request along the chain until an object handles it.  Each object either handles the request or passes it to the next object in the chain.
Chain of Responsibility
Chain of Responsibility Use Chain of Responsibility when  more than one object may handle a request, and the handler isn't known  apriori . The handler should be ascertained automatically.  you want to issue a request to one of several objects without specifying the receiver explicitly.  the set of objects that can handle a request should be specified dynamically.
Chain of Responsibility Chain consists of a series of responder objects (that is, objects inheriting from  UIResponder )  If a given responder object doesn’t handle a particular message, it passes the message to the next responder in the chain  An application can have as many responder chains as it has windows Only one responder chain can be active at a time—the one associated with the currently active window.
Chain of Responsibility If a view is managed by a UIViewController object, the view controller becomes the next responder in the chain. The design of the view hierarchy, which is closely related to the responder chain, adapts the Composite pattern.  Action messages—messages originating from control objects—are based on the target-action mechanism, which is an instance of the Command pattern.
Composite Compose related objects into tree structures to represent part-whole hierarchies.  Composite lets clients treat individual objects and compositions of objects uniformly.
Composite
Composite Use the Composite pattern when you want to represent part-whole hierarchies of objects.  you want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the  composite structure uniformly.
Composite The views in a window are internally structured into a view hierarchy.  At the root of the hierarchy is a window  and its content view, a transparent view that fills the window’s content rectangle.  Views that are added to the content view become subviews of it, and they become the superviews of any views added to them.  A view can have one (and only one) superview and zero or more subviews.
Composite
Iterator Provide an interface to access the elements of an aggregate object  sequentially without exposing its underlying representation. transfers the responsibility for accessing the elements  from the collection to an iterator.  Different iterators can carry out different traversal policies.
Iterator Use the Iterator pattern to access an aggregate object's contents without exposing its internal representation. to support multiple traversals of aggregate objects.  to provide a uniform interface for traversing different aggregate structures.
Iterator
Iterator The  NSEnumerator  class in the Foundation framework implements the Iterator pattern.  Instances of  NSDirectoryEnumerator  class recursively enumerate the contents of a directory in the file system. The collection classes such as  NSArray ,  NSSet , and  NSDictionary  include methods that return an enumerator appropriate to the type of collection.
Memento The Memento pattern captures and externalizes an object’s internal state—without violating encapsulation—so that the object can be restored to this state later. The Memento pattern keeps the important state of a key object external from that object to maintain cohesion.
Memento
Memento Use the Memento pattern when  a snapshot of (some portion of) an object's state must be saved so that it can be restored to that state later,  and  a direct interface to obtaining the state would expose implementation  details and break the object's encapsulation.
Memento Archiving converts the objects in a program, along with those objects’ properties (attributes and relationships) into an archive that can be stored in the file system or transmitted between processes or across a network. The archive captures the object graph of a program as an architecture-independent stream of bytes that preserves the identity of the objects and the relationships among them. object’s type is stored along with its data. Encoding and decoding are operations that you perform using an  NSCoder  object, preferably using the keyed archiving technique (using  NSKeyedArchiver  classes).  The object being encoded and decoded must conform to the  NSCoding  protocol

Pavel_Kravchenko_Mobile Development

  • 1.
    Cocoa Design PatternsPavel Kravchenko, Ciklum
  • 2.
    What is aDesign Pattern? A design pattern is: a template for a design that solves a general problem a tool of abstraction that is useful in architecture A vocabulary to use when explaining complex software
  • 3.
    Design principles encapsulatethe aspects of system structure program to an interface, not an implementation Minimize coupling
  • 4.
    The Command encapsulatea request as an object and Separates message sender and reciever
  • 5.
  • 6.
    The Command Usewhen you want to: parameterize objects by an action to perform (Commands are an object-oriented replacement for callbacks). specify and execute requests at different times (you can transfer a command object to a different process). support undo. support logging changes.
  • 7.
    The Command Example:NSInvocation (encapsulates an Objective-C message) An invocation object contains a target object, method selector, and method arguments You can dynamically change its target and arguments you can also obtain the return value from the object you can repeatedly invoke a message with multiple variations in target and arguments
  • 8.
    Abstract Factory Providean interface for creating families of related or dependent objects without specifying their concrete classes. The client is decoupled from any of the specifics of the concrete object obtained from the factory.
  • 9.
  • 10.
    Abstract Factory Usethe Abstract Factory pattern when: • a system should be independent of how its products are created and represented. • a system should be configured with one of multiple families of products. • a family of related product objects is designed to be used together
  • 11.
    Class cluster Aclass cluster is an architecture that groups a number of private, concrete subclasses under an abstract superclass. The abstract superclass declares methods for creating instances of its private subclasses. Each object returned may belong to a different private concrete subclass. you don’t, and can’t, choose the class of the instance.
  • 12.
    Class cluster NSNumber*aChar = [NSNumber numberWithChar:’a’]; NSNumber *anInt = [NSNumber numberWithInt:1]; NSNumber *aFloat = [NSNumber numberWithFloat:1.0]; NSNumber *aDouble = [NSNumber numberWithDouble:1.0];
  • 13.
    Class cluster Sincenumbers of different types can be converted from one type to another and can be represented as strings, for example, they could be represented by a single class. aChar , anInt , aFloat , aDouble —are objects of different private subclasses but them interfaces declared by the NSNumber Don't release objects returned from factory methods
  • 14.
    Chain of ResponsibilityAvoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. Each object either handles the request or passes it to the next object in the chain.
  • 15.
  • 16.
    Chain of ResponsibilityUse Chain of Responsibility when more than one object may handle a request, and the handler isn't known apriori . The handler should be ascertained automatically. you want to issue a request to one of several objects without specifying the receiver explicitly. the set of objects that can handle a request should be specified dynamically.
  • 17.
    Chain of ResponsibilityChain consists of a series of responder objects (that is, objects inheriting from UIResponder ) If a given responder object doesn’t handle a particular message, it passes the message to the next responder in the chain An application can have as many responder chains as it has windows Only one responder chain can be active at a time—the one associated with the currently active window.
  • 18.
    Chain of ResponsibilityIf a view is managed by a UIViewController object, the view controller becomes the next responder in the chain. The design of the view hierarchy, which is closely related to the responder chain, adapts the Composite pattern. Action messages—messages originating from control objects—are based on the target-action mechanism, which is an instance of the Command pattern.
  • 19.
    Composite Compose relatedobjects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
  • 20.
  • 21.
    Composite Use theComposite pattern when you want to represent part-whole hierarchies of objects. you want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly.
  • 22.
    Composite The viewsin a window are internally structured into a view hierarchy. At the root of the hierarchy is a window and its content view, a transparent view that fills the window’s content rectangle. Views that are added to the content view become subviews of it, and they become the superviews of any views added to them. A view can have one (and only one) superview and zero or more subviews.
  • 23.
  • 24.
    Iterator Provide aninterface to access the elements of an aggregate object sequentially without exposing its underlying representation. transfers the responsibility for accessing the elements from the collection to an iterator. Different iterators can carry out different traversal policies.
  • 25.
    Iterator Use theIterator pattern to access an aggregate object's contents without exposing its internal representation. to support multiple traversals of aggregate objects. to provide a uniform interface for traversing different aggregate structures.
  • 26.
  • 27.
    Iterator The NSEnumerator class in the Foundation framework implements the Iterator pattern. Instances of NSDirectoryEnumerator class recursively enumerate the contents of a directory in the file system. The collection classes such as NSArray , NSSet , and NSDictionary include methods that return an enumerator appropriate to the type of collection.
  • 28.
    Memento The Mementopattern captures and externalizes an object’s internal state—without violating encapsulation—so that the object can be restored to this state later. The Memento pattern keeps the important state of a key object external from that object to maintain cohesion.
  • 29.
  • 30.
    Memento Use theMemento pattern when a snapshot of (some portion of) an object's state must be saved so that it can be restored to that state later, and a direct interface to obtaining the state would expose implementation details and break the object's encapsulation.
  • 31.
    Memento Archiving convertsthe objects in a program, along with those objects’ properties (attributes and relationships) into an archive that can be stored in the file system or transmitted between processes or across a network. The archive captures the object graph of a program as an architecture-independent stream of bytes that preserves the identity of the objects and the relationships among them. object’s type is stored along with its data. Encoding and decoding are operations that you perform using an NSCoder object, preferably using the keyed archiving technique (using NSKeyedArchiver classes). The object being encoded and decoded must conform to the NSCoding protocol

Editor's Notes

  • #4 Посмотреть, что это за боги EventLoop
  • #5 Пример с пареметризацией пункта меню
  • #7 NSUndoManager почитать
  • #8 Посмотреть RunTime Programming Guide Посмотреть на временные задержки вызова операций На возврат результата из метода, инвокешна и селектора На сохранение инвокешна на диск или в память
  • #11 Последние 2 абзаца!
  • #13 Посмотреть какие еще числа могут быть
  • #15 Пример с пунктами меню Windows! ?
  • #18 Методы UIResponder'a Иехархия наследования Количество окон в приложении NextResponder UIViewController'a
  • #19 Target-Action механизм
  • #21 Пример с графическим редактором
  • #23 Как добавить к иерахии поддержку какого нибудь нового метода? Категория?!
  • #24 Может сюда другую картинку? Сделать самому
  • #27 Дочитать про итератор
  • #28 Посмотреть на NSEnumerator NSDirecrotyEnumerator NSSet NSEnumerator *enumerator = [anArray objectEnumerator]; while ((object = [enumerator nextObject])) { } NSDirectoryEnumerator *enumerator = [[ NSFileManager defaultManager] enumeratorAtPath: path]; while (curObject = [enumerator nextObject]) { }
  • #31 NSString * dataPath = [ _docPath stringByAppendingPathComponent : kDataFile ] ; NSMutableData * data = [[ NSMutableData alloc ] init ] ; NSKeyedArchiver * archiver = [[ NSKeyedArchiver alloc ] initForWritingWithMutableData : data ] ; [ archiver encodeObject : _data forKey : kDataKey ] ; [ archiver finishEncoding ] ; [ data writeToFile : dataPath atomically : YES ] ; [ archiver release ] ; [ data release ] ;
  • #32 Посмотреть на методы NSCoder Поддерживает ли его NSInvocation NSCoding Узнать о внутреннем строении О битовом представлении О NSData - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:mapName forKey:@"MVMapName"]; [coder encodeFloat:magnification forKey:@"MVMagnification"]; [coder encodeObject:legendView forKey:@"MVLegend"]; [coder encodeConditionalObject:auxiliaryView forKey:@"MVAuxView"]; }