iOS常用设计模式

抽象工厂

抽象工厂模式提供了一个接口,用于创建相关或依赖对象的族,而不指定具体的类。 客户与从工厂获得的具体对象的任何具体细节分离。

类集群

类集群是一种将公共抽象父类下的许多私有具体子类组织在一起的体系结构。 抽象父类声明了创建其私有子类实例的方法。 父类根据调用的创建方法分配适当的具体子类的对象。 每个返回的对象可能属于不同的私有具体子类。
Cocoa中的类集群只能生成其数据存储可能因环境而异的具体对象。 Foundation框架具有NSString ,NSData, NSDictionary,NSSet和NSArray对象的类集群。 公共父类包括这些不可变类以及互补的可变类NSMutableString , NSMutableData ,NSMutableDictionary , NSMutableSet和NSMutableArray。

适配器

适配器设计模式将类的接口转换为客户期望的另一个接口。 适配器让类能够协同工作。 它将客户从目标对象的类中分离出来。

责任链

责任链设计模式通过给予多个对象一个机会来处理请求,从而将请求的发送者与其接收者分离。 该模式将接收对象链接在一起,并沿着链传递请求,直到对象处理它为止。 链中的每个对象处理请求或将其传递给链中的下一个对象。

响应者链

应用程序框架包括称为响应者链的体系结构。 这个链由一系列响应者对象组成(也就是继承对象) NSResponder 或者,在UIKit中, UIResponder ),一个事件(例如,一个鼠标点击)或动作消息被传递(通常)最终被处理。 如果给定的响应者对象不处理特定的消息,则将消息传递给链中的下一个响应者。 响应者对象在链中的顺序通常由视图层次结构决定,从层次结构中的低级响应者到高层响应者的进程,最终在管理视图层次的窗口对象,窗口对象的委托,或全局应用程序对象。 响应者链上的事件和行动消息的路径是不同的。 应用程序可以拥有尽可能多的响应者链,因为它具有窗口(甚至是本地层次的视图)。 但是一次只能有一个响应者链,即与当前活动窗口关联的响应者链。

命令

命令设计模式将请求作为对象进行封装,从而使您可以使用不同请求参数化客户端,排队或记录请求,并支持可撤销操作。 请求对象将特定接收者上的一个或多个动作绑定在一起。 命令模式将发出请求的对象与接收和执行该请求的对象分开。

调用对象

一个实例 NSInvocation 类封装了一个 Objective-C消息。 一个调用对象包含一个目标对象,方法选择器和方法参数。 您可以动态地更改调用对象调度的消息的目标及其参数; 一旦调用被执行,您也可以从对象中获取返回值。 使用单个调用对象,您可以重复调用目标和参数具有多种变化的消息。

创建一个NSInvocation对象需要一个NSMethodSignature对象,它是一个封装了与方法的参数和返回值有关的类型信息的对象。 NSMethodSignature对象又是从方法选择器创建的。 NSInvocation的实现也利用了Objective-C runtime 的功能。

Target-Action 机制

该 target-action机制使控件对象(即按钮,滑块或文本字段等对象)能够将消息发送到另一个可以解释消息并将其作为特定于应用程序的指令处理的对象。 接收对象,或者 目标,通常是一个自定义控制器对象。 消息命名为 动作消息 - 由选择器确定,一个方法的唯一运行时标识符。

组合模式

组合模式将相关对象组合成树结构来表示部分 - 整体层次结构。 该模式可以让客户统一处理个别对象和对象组合。

视图层次结构

View ( NSView 要么 UIView 对象)在一个窗口内部结构化成一个 视图层次。 在层次结构的根部是一个窗口( NSWindow 要么 UIWindow 对象)及其内容视图,一个透明视图,填充窗口的内容矩形。 添加到内容视图中的视图成为其子视图,并成为添加到视图中的所有视图的超级视图。 除了内容视图外,视图还有一个(也是唯一的) superview和零或任何数量的 子视图。

视图层次结构是在绘图和事件处理中起作用的结构体系结构。 一个视图有两个边界矩形,它的框架和边界,这些矩形会影响视图的图形操作。 框架是外部边界; 它将视图定位在其超级视图的坐标系中,定义其大小,并将绘图剪辑到视图的边缘。 边界(内部边界矩形)定义视图自身绘制的曲面的内部坐标系。

当窗口系统要求窗口准备显示时,要求超级视图在其子视图之前进行渲染。 当你发送一些消息到一个视图 - 例如,一个请求视图重绘自己的消息 - 消息传播到子视图。 因此,您可以将视图层次结构的分支视为统一的视图。

装饰器

装饰设计模式动态地将额外的责任附加到对象上。 装饰器为扩展功能提供了子类化的灵活替代方案。 与子类化一样,修饰器模式的适应性允许您在不修改现有代码的情况下合并新的行为。 装饰器包装了它们扩展行为的类的一个对象。 它们实现与它们所包装的对象相同的接口,并在将任务委托给包装对象之前或之后添加它们自己的行为。 Decorator模式表达了这样的设计原则:类应该是可以拓展的,而不需要修改类。

分类(Categories)

一个 category是Objective-C语言的一个特性,它使您能够将方法(接口和实现)添加到类中,而无需创建子类。 在程序范围内,类的原始方法和类别添加的方法之间没有运行时差异。 类别中的方法成为类类型的一部分,并由所有类的子类继承。类别并不是对装饰者模式的严格适应,而是采取了不同的途径来实现这个意图。 按类别添加的行为是编译时工件,并不是动态获取的。 而且,类别不会封装正在扩展的类的一个实例。

迭代器

Iterator设计模式提供了一种方法来顺序访问聚合对象的(即,集合)元件,而不暴露其底层表示。迭代器模式转换用于访问和遍历从集合本身集合的元素添加到迭代器对象的责任。迭代器定义了一个接口,用于访问集合元素和跟踪当前的元素。不同的迭代器可以执行不同的遍历策略。

枚举器

Foundation框架的NSEnumerator类实现了迭代器模式。抽象NSEnumerator类的私人、具体的子类返回枚举对象,顺序返回集合中的对象给客户,有各种类型-数组,集合,词典(值和键)。

中介者模式

中介者模式定义了如何封装一组互动对象的对象。中介者促进由称呼对方明确地保持对象的松散耦合,并可以独立地改变它们之间的相互作用。因此,这些对象可以保持更多的重用。此模式的一个“中介对象”集中在一个系统中对象之间复杂的通信和控制逻辑。这些对象告诉中介对象当其状态的变化,反过来,从介体对象请求作出响应。

AppKit框架控制器类

模型 - 视图 - 控制器设计模式给在一个面向对象的系统(例如应用)中的对象分配角色。它们可以是模型对象,其中包含应用程序的数据和操作这些数据; 它们可以是view对象,可以显示数据和响应用户的动作; 或者它们可以是控制器对象,作为所述模型和视图对象之间的中介。控制器对象适合中介者模式。

在Cocoa中,控制器对象可以是两种通用的类型: 中介控制器或 协调控制器。中介调解的控制器查看对象和模型对象之间的数据在应用程序的流程。中介控制器通常是NSController对象。协调控制器执行集中通信和控制逻辑用于应用,作为代理对框架对象和作为行动的消息的目标。他们是典型的NSWindowController对象或自定义NSObject对象子类。因为他们是如此高度专业化的特定程序,以协调控制器往往不被重用。

抽象类NSController和AppKit框架中它的具体子类是Cocoa绑定技术的一部分,它会自动同步包含在模型对象和显示和查看对象编辑的数据的一部分。例如,如果用户在text field编辑字符串,绑定技术传达变化,通过一个中介控制器到绑定模型对象的相应属性。所有的程序员需要做的就是正确设计自己的模型对象,并使用Interface Builder,建立一个程序的视图,控制器,和模型对象之间的绑定。

Interface Builder库中具体的公共控制器类的实例是可用的,因此是高度可重用。他们提供的服务,如选择和占位符值的管理。这些对象执行以下具体功能:

NSObjectController 管理一个模型对象。
NSArrayController管理模型对象的数组,并保持一个选择; 它也可以让你的对象从array中添加和删除对象。
NSTreeController 使您能够以分层树结构中添加,删除和管理模型对象。
NSUserDefaultsController提供了一个方便的接口首选项(用户缺省值)系统。

备忘录模式

备忘录模式捕捉和外部化对象的内部状态,而不违反封装-使得对象可以恢复到这种状态后。备忘录模式保持关键对象外部的重要状态。

归档

将对象存档在一个程序中,随着这些对象的属性(属性和关系)到档案,可以存储在文件系统或过程或在网络之间传输。

NSCoder

编码和解码使用NSCoder对象执行的操作,最好使用密钥归档技术(你要调用的方法NSKeyedArchiver和NSKeyedUnarchiver类)。被编码和解码的对象必须符合NSCoding协议;该协议的方法被调用时归档。

属性列表序列化

属性列表是一个简单的,使用下面类对象结构序列化的对象图:NSDictionary, NSArray, NSString, NSData,NSDate, NSNumber.这些对象通常被称为属性列表对象。几个Cocoa框架类提供的方法来将这些属性列表对象和定义数据流记录的对象及其层次关系的特殊格式的内容。这个NSPropertyListSerialization类提供的类方法,可以从XML格式或优化的二进制格式,序列化属性列表对象。

Core Data

Core Data是Cocoa框架,定义了管理对象图,使他们持续的架构。正是这第二能力对象持久化使Core Data适应备忘录模式。

观察者

观察者设计模式定义了对象之间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的通知并自动更新。观察者模式本质上是一个发布和订阅模型,它的主体及其观察员是松散耦合。观察和观察对象之间不需要知道对方就可以发生通信。

通知

Cocoa通知机制实现了一个基于观察者模式的消息一对多广播。在一个程序中的对象添加自己或其他对象的列表,有一个或多个通知观察者,其中每一个是由全局的字符串识别(通知的名字)。要通知其它对象,观察对象创建一个通知对象和推送到通知中心的对象。通知中心决定一个特定的通知观察者,通过消息将通知发送到他们。该方法通过通知消息调用必须符合一定的单参数签名。该方法的参数是通知对象,其中包含通知名,观察对象,和一个包含任何补充信息字典。推送通知是一个同步程序。发布对象不重新控制到通知中心有广播通知所有的观察者。对于异步行为,你可以在通知队列中通知;控制立即返回到发布对象,当通知到达队列顶部时通知中心再广播。定期通知,这些通过通知中心的广播只是进程内。如果你想给其他进程广播通知,您可以使用分布式通知中心及其相关的API。

KVO

KVO是一种机制,允许当其他对象的具体特性的变化时对象被通知。它是基于NSKeyValueObserving 非正式协议。观察到的属性可以是简单的属性,一个一关系,或一对多的关系。在模型视图控制器模式下,键值观察尤为重要,因为它使视图对象模型对象的观察通过控制器层的变化。因此,这是Cocoa的一个必不可少的绑定技术的组成部分。

Cocoa提供了一个默认“自动”的实施NSKeyValueObserving方法:给所有符合对象的属性的观察能力。

代理

代理设计模式提供了一种替代,或占位符,为另一个对象来控制访问其他对象。使用这个模式来创建一个代表或代理,对象,控制访问另一个对象,这可能是远程的,复杂的创建,或需要保护。这种模式的结构类似于装饰模式却有不同的用途;装饰给对象添加行为,而代理控制对对象的访问。

NSProxy

NSProxy类定义了对象作为其他对象的代理对象的接口,甚至对象还不存在。一个代理对象通常转发消息给它代表的对象,但它也可以响应消息,通过加载对象转变为它或代表。虽然NSProxy是一个抽象类,它实现了NSObject协议和其他基本方法的根对象的预期;事实上,一个层次结构的基类,如NSObject类

具体的NSProxy子类能够完成既定目标的代理模式,如昂贵的对象或作为安全哨兵懒实例化对象。NSDistantObject,基础框架中一个NSProxy具体子类,实现了一个远程代理,对于透明的分布式消息。NSDistantObject对象是分布式对象结构的一部分。作为对其他进程或线程对象的代理,它们有助于使这些线程或进程的对象之间的通信。

单例(Singleton)

单例设计模式确保一个类只有一个实例,并提供一个访问它的全局访问点。这类跟踪它的唯一实例,可以确保没有其他实例可以被创建。单例类是适当的情况下,对于提供一个全球性的资源是有意义的一个对象。

框架类

几个Cocoa框架类是单例。他们包括NSFileManager,NSWorkspace,NSApplication以及在UIKit中,UIApplication。一个进程是限制这些类只有一个实例。当客户端请求一个实例的类,它获取一个共享实例,这是建立在第一次请求时懒创建的。

外观

外观设计模式为子系统中的一组接口提供统一的接口。 该模式定义了一个更高层次的接口,通过降低复杂度并隐藏子系统之间的通信和依赖关系,使子系统更易于使用。

NSImage

NSImage 类 ,AppKit框架提供一个统一的接口用于装载和使用图像,可以是基于位图(例如在JPEG,PNG,TIFF或格式)或基于向量的(例如在EPS或PDF格式)。NSImage可以保持相同的图像的一个以上表示;每个表示是一种 NSImageRep 对象。 NSImage自动化选择一种表现,对于一个特定类型的数据和对于给定的显示装置是合适的。它也隐藏了图像操作和选择的细节,使客户可以互换使用许多不同的底层表示。

模板方法

模板方法设计模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类。模板方法模式让子类重新定义算法中的某些步骤而不改变算法的结构。

UITableView的DataSource

UITableView的DataSource通过提供一组模板方法,使用者实现根据模板实现具体的方法,用于展示一个列表。

模板模式和外观模式的区别

外观模式实现的是多各类协作共同完成一件事情,因此我们使用一个函数来封装这些操作,(将这个函数放在一个类中)。
模板模式实现的是一个类的多个函数组合完成一件事情,虽然类的每个函数可能有不同的实现方式,但是流程是一样的。因此使用继承方式,在类中新建一个函数依次调用其他的成员函数。
模板模式中将一个大函数拆分为小函数,然后又将小函数封装为一个函数。

建造者模式

是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。

建造者模式通常包括下面几个角色
1、Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
2、ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。
3、Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
4、Product:要创建的复杂对象。

建造者模式应用实例

在FaceBook的开源动画框架POP中应用了建造者模式用:

POPAnimatableProperty *animatableProperty = [POPAnimatableProperty propertyWithName:@"property" initializer:^(POPMutableAnimatableProperty *prop) {
    prop.writeBlock = ^(id obj, const CGFloat values[]) {
    };
    prop.readBlock = ^(id obj, CGFloat values[]) {
    };
}];

这里的initializer本质上就是builder,只是叫法不同而已。

建造者模式和模板模式的区别

建造者是使用组合方式实现不同的表示,而模板方法使用的是继承的方式。组合优于继承。模板模式由父类实现调用过程,实现细节在子类中区分;成员函数(protected)。建造者模式父类提供接口,子类负责实现;具体实现流程由建造者类通过接口实现。
建造者抽象的是构建过程,而模板方法提取的是实现公共。

访问者模式

对于一组数据结构比较稳定的对象,在不改变数据结构的前提下,增加作用于这些结构元素新的功能。

数组排序
NSArray *list = @[@"张三", @"李四", @"王五"];
    [list sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        return [obj1 compare:obj2];
    }];

数组的排序算法中,排序的基本算法是固定不变的,变化的是不同对象的比较方法。因此对象将对象的比较实现交给使用方实现,而数组内部通过调用使用者提供的比较方法,实现功能的扩展。与迭代器模式的主要区别是,迭代器模式主要用于遍历对象,而访问者模式主要用于读取和操作对象的内容。

享元模式

享元模式主要用于减少同一类对象的大量创建,以减少内存占用,提高项目流畅度。

UITableViewCell的缓存池

在iOS开发中,大家肯定都用过UITableViewCell,UICollectionViewCell,这两个类在使用过程中就使用了享元模式,工作原理基本就是:利用重用池重用思想,创建页面可显示的cell个数的对象,在页面滚动过程中监听每个cell的状态,从页面消失的cell被放回重用池,将要显示的cell先去重用池中去取,如果可以取到,则继续使用这个cell,如果没有多余的cell,就重新创建新的,这样即使你有100条数据,也仅仅只会创建页面可显示个数的cell对象,这样就大大减少了对象的创建,实现了大量内存占用,导致内存泄露的问题。

中介者模式

用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
房地产中介就类似于中介者,买家要买房,直接到中介看房源,卖家卖房,直接委托中介推销,买卖家通过中介相互取得联系,进行沟通,最后达成买卖共识。

MVC

MVC模式是中介者模式的一种表现形式,Comtroller(中介者)承担两个同事类(View和Modle)之间的中转和协调作用。

中介者模式的优点
①解耦合
模式中把多个同事类的交互逻辑封装在中介类中,同事类之间不再相互依赖引用,各个同事类可以独立变化。
②把交互逻辑集中管理
当同事类间的交互发生变化时,只需要在中介者修改逻辑,提高了开发效率又降低了维护成本,可谓一举两得。
中介者模式的缺点
中介者模式的优点如果使用不好可能就变成了缺点,由于交互逻辑的高度集中化,中介者会随着业务逻辑的不断增加而变得臃肿膨胀,变得难以管理。

你可能感兴趣的:(iOS常用设计模式)