本篇文章将Gang of Four中所列举的设计模式在Objective-C中的使用从名称,定义,何时使用,UML图以及在Cocoa Touch中的应用五个维度做出了总结。具体的列表请看下图。因为本人水平有限,所以有错误或者不正确的地方欢迎提出意见和建议。
名称 |
定义 |
何时使用 |
UML图 |
Cocoa Touch中的使用 |
Prototype(原型) |
Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype. |
1.创建的对象独立于它是什么和它是如何被创建的; 2.要实例化的类在运行时刻指定; 3.我们不想有一个和产品一个层次的工厂; 4.不同类的实例间的差别只是一些组合的状态,通过复制来创建更方便一些; 5.类并不容易被创建时,比如组合中的对象又各自包含对象时。 |
NSCopying代理中的 copyWithZone方法。 |
|
Factory Method(工厂方法) |
Define an interface for creating an object, but letsubclasses decide which class to instantiate. Factory Method lets a class defer instantiation tosubclasses. |
1.需要创建的对象的类在编译时无法预料; 2.一个类想让其子类在运行时绝对创建什么; 3.一个类拥有一些帮助类作为它的子类,并且你想要具体返回哪一个的局部知识。 |
Factory methods can be seen almost everywhere in the Cocoa Touch framework. Such that some “convenience” methods that |
|
Abstract Factory(抽象工厂) |
Provides an interface for creating families of related or dependent objectswithout specifying their concrete classes. |
|||
Builder(创建者) |
Separates the construction of a complex object from its representationso that the same construction process can create different representations. |
1.你想要创建一个复杂的包含好几个步骤的对象。创建它的算法应该独立于每个部分是如何创建的。 2.你需要一个用不同步骤创建一个对象的创建步骤。 |
||
Singleton(单例) |
Ensures a class has only one instance, and provide a global point ofaccess to it. |
1.某个类必须有且只有一个实例,并且只能通过一个被熟知的方法访问。 2.这个仅有的实例仅仅可以通过子类化来进行拓展,而且拓展不会破坏client代码。 |
UIApplication, |
|
Adapter(适配器) |
Converts the interface of a class into another interface clients expect.Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. |
1.已存在的类的接口不符合你的要求。 2.你想要一个可以复用的类和一个也许没有合适的接口的类协作。 3.你需要适配一个类的很多子类,但是又不可能让它们每个类都生成一个适配器子类。所以你可以使用一个对象适配器(delegate)来适配它们父类的方法。 |
|
delegate, block |
Bridge(桥接) |
Decouples an abstraction from its implementation so that the two canvary independently. |
1.你不想将一个抽象和它的实现永远绑定在一起。 2.抽象和它的实现都会被子类拓展。 3.改变一个抽象的实现并不会影响client code 4.如果为了使一个实现更好而需要一个额外的子类,那么说明需要把实现和抽象分离了。 5.你想将一个实现在不同对象的抽象中进行分享。 |
||
Facade(外观) |
Provides a unified interface to a set of interfaces in a system. Fac?adedefines a higher-level interface that makes the subsystem easier to use. |
1.你的子系统变得特别复杂。为了实现一个功能需要涉及好的的类,你就可以使用一个外观来提供一个操作这些类的简单的接口。 2.你可以使用外观来对你的子系统进行分层。每个子系统都只有一个外观进行访问。你可以让他们只简单地通过外观来进行通信。 |
||
Mediator(中介者) |
Defines an object that encapsulates how a set of objects interacts.Mediator promotes loose coupling by keeping objects from referring to each other explicitly, andit lets you vary their interaction |
1.一组对象互相独立并且由于它们之间复杂的交互难以理解它们的关系。 2.由于一个对象和其他的很多对象相互指向和交互使其难以重复利用。 3.一个逻辑或者行为被在很多类中分发则需要不通过子类化的方式进行配置。 |
||
Observer (观察者) |
Defines a one-to-many dependency between objects so that whenone object changes state, all its dependents are notified and updated automatically. |
1.有两种抽象并且彼此依赖。将它们封装在不同的对象中允许你独立地改变和重用它们。 2.一个对象的改变也要求改变别的对象,并且被改变的对象的数量是不固定的。 3.一个对象需要在不知道别的对象是什么的情况下通知其他对象。 |
Notification, KVO | |
Composite(复合) |
Compose objects into tree structures to represent part-wholehierarchies. Composite lets clients treat individual objects and compositions of objectsuniformly. |
1.你想用抽象树来呈现一些对象。 2.你想要client以相同的方式对待一组对象和独立的对象。 |
UIViews | |
Iterator(遍历者) |
Provide a way to access to the elements of an aggregate object sequentially withoutexposing its underlying representation. |
1.你需要在不暴露一个复合对象的内部表现的情况下访问一个复合对象中的内容。 2.你需要以不同的方式穿越复合对象。 3.你需要提供一种统一的方式来遍历不同类型的复合对象。 |
NSEnumerator | |
Visitor(访问者) |
The Visitor pattern represents an operation to be performed on the elements of an objectstructure. Visitor lets you define a new operation without changing the classes of the elements onwhich |
1.一个复杂的对象结构包含很多的其他的有着不同接口的对象,你想要根据他们实际的类型做不同的操作。 2.你想要对一个复合结构中的对象做无关的操作,并且这些操作不会污染这些类。你可以把有关的操作放在一个访问这类中然后在需要时使用这些操作。 3.你经常需要向一个结构稳定的类中增加新的复杂操作。 |
||
Decorator(装饰者) |
Attaches additional responsibilities to an object dynamically.Decorators provide a flexible alternative to subclassing for extending functionality. |
1.你想要动态地和显示地并且不影响其他对象地为一些对象增加一些操作。 2.你想要给一个不可能拓展的类增加新的行为。当一个类的定义是隐藏的或者不允许被子类化。 3.拓展一个类的行为是可选择的时候。 |
||
Chain of Responsibility (职责链) |
To avoid coupling the sender of a request to its receiverby giving more than one object a chance to handle the request. It chains the receiving objectsand passes the request along the chain |
1.有一个以上的对象可能对一个请求进行处理,但是具体是哪一个只有在运行时才知道。 2.你想要对一组的对象发起一个请求但是并不指定究竟是哪一个来处理这个请求。 |
||
Template Method(模板方法) |
Define the skeleton of an algorithm in an operation,deferring some steps to subclasses. Template Method lets subclasses redefine certain steps ofan algorithm without changing the algorithm‘s |
1.你需要一次性实现一个算法中不变的部分并且把那些特殊的行为留到子类中去实现。 2.子类中通用的行为可以被放入一个公用类中避免代码冗余。已存在代码中的差异需要被放进新的操作中。你使用模板方法代替这些新的代码时调用每个新的操作。 3.子类的拓展必须是可控的。你可以在某个点上定义一个”hook”操作。子类可以在hook上进行拓展操作。 |
UIView中的drawRect:方法 rotatingHeaderView rotatingFooterViewwillAnimateRotationToInterfaceOrientation:duration:willRotateToInterfaceOrientation:duration: |
|
Strategy(策略) |
Define a family of algorithms, encapsulate each one, and makethem interchangeable. Strategy lets the algorithm vary independently from clients that use it. |
1.一个类在它的操作中使用不同的条件来定义不同的行为。你可以将相关的条件分支放进他们自己的策略类中。 2.你在一个算法中需要不同的变体。 3.你需要避免在用户面前暴露算法的复杂性和算法相关的数据。 |
||
Command(命令) |
Encapsulate a request as an object, thereby letting you parameterizeclients with different requests, queue or log requests, and support undoable operations. |
1.你想让你的程序支持undo/redo 2.你想将一个动作参数化为一个对象并通过不同的命令来执行操作和替换回调。 3.你想要指定,队列和执行一个请求在不同的时间点。 4.你想要记录变化所以他们可以再系统故障时被重新恢复。 5.你想让系统支持一个封装了很多数据变化的业务。这个业务可以被模块化为一个命令对象。 |
|
|
Flyweight(享元) |
Uses sharing to support large numbers of fine-grained objectsefficiently. |
1.你的应用使用很多对象。 2.在内存中加载对象会影响内存性能。 3.很多对象的唯一状态可以被外部化或者轻量级化。 4.一些相关的被分享的对象可以替换原来的一些对象,在对象的唯一状态被去掉后。 5.你的应用不依赖对象的ID因为被分享的对象不可以有唯一标示符。 |
||
Proxy(代理) |
Provides a surrogate or placeholder for another object to control accessto it. |
1.你需要一个遥远的代理提供一个本地的表现性来代表一个在不同位置上的对象或者互联网上的对象。 2.你需要一个虚拟代理来创建重量级的对象,根据要求。 3.你需要一个保护代理来基于不同的访问权限控制对于原始对象的访问请求。 4.你需要一个智能引用代理来对访问真正对象的引用进行计数。它同样可以用来锁住原始对象来让其他对象无法修改它。 |
NSProxy | |
Memento(备忘录) |
Without violating encapsulation, capture and externalize an object’sinternal state so that the object can be restored to this state later. |
1.你需要保存一个对象的状态为snapshot或者它的一部分,将来可以将其进行恢复。 2.你需要隐藏这个如果获得状态就会暴露其实现的接口。 |
The Cocoa Touch framework has adopted the Memento pattern with archiving, propertylist serialization, and core data. |