iOS设计模式
适配器,责任链,装饰器,门面
在本文中,我将介绍四种设计模式,您可以将它们与当前项目相关联,并且可以通过示例(例如可可如何适应这些模式)轻松理解。 让我们从适配器开始。
适配器设计模式将类的接口转换为客户端期望的另一个接口。 Adapter使类可以协同工作,否则由于接口不兼容而无法实现。 它将客户端与目标对象的类分离。
可可如何适应适配器设计模式?
通讯协定
协议是一种语言级别的(Objective-C)功能,可以定义作为适配器模式实例的接口。 协议本质上是一系列与类无关的方法声明。 (在Java中, 接口与协议同义。)如果希望客户端对象与另一个对象进行通信,但是对象的不兼容接口使此操作变得困难,则可以定义协议。 然后,另一个对象的类正式采用该协议,并通过实现该协议的一种或多种方法来“符合”该协议。 该协议可能需要一致的类来实现其某些方法,而其他类的实现则可选。 然后,客户端对象可以通过协议接口将消息发送到另一个对象。
注意:协议的设计与适配器模式的描述不完全匹配。 但这达到了模式的目标:允许具有其他不兼容接口的类一起工作。
用途和局限性
例如,Foundation框架包括NSObject
, NSCopying
和NSCoding
协议,它们都是非常重要的协议。 AppKit协议包括NSDraggingInfo
, NSTextInput
和NSChangeSpelling
。 UIKit协议包括UITextInputTraits
, UIWebViewDelegate
和UITableViewDataSource
。
责任链设计模式通过为多个对象提供处理请求的机会,将请求的发送者与接收者分离。 模式将接收的对象链接在一起,并沿着链传递请求,直到对象处理它为止。 链中的每个对象要么处理请求,要么将请求传递给链中的下一个对象。
可可如何适应责任链设计模式?
响应链
应用程序框架包括称为响应者链的体系结构。 该链由一系列响应程序对象(即,从NSResponder
继承的对象,或者在UIKit中,从UIResponder
继承的UIResponder
)组成,事件(例如,鼠标单击)或操作消息将沿着该UIResponder
传递并(通常)最终得到处理。 如果给定的响应者对象不处理特定消息,则它将消息传递给链中的下一个响应者。 响应者对象在链中的顺序通常由视图层次结构决定,层次结构中从低层响应者到高级响应者的发展,最终以管理视图层次结构的窗口对象,窗口对象的委托,或全局应用程序对象。 响应者链上事件和操作消息的路径是不同的。 一个应用程序可以具有与窗口(甚至视图的局部层次结构)一样多的响应者链。 但是一次只能有一个响应者链处于活动状态,即与当前活动窗口关联的响应链。
注意:与响应者链密切相关的视图层次结构的设计适应了Composite模式。
用途和局限性
通过使用Interface Builder或以编程方式为程序构造用户界面时,您可以“免费”获得一个或多个响应者链。响应者链与视图层次结构紧密相关,在您创建视图时会自动获得它。对象是窗口内容视图的子视图。 如果您有一个自定义视图添加到视图层次结构,它将成为响应者链的一部分。 如果实现适当的NSResponder
或UIResponder
方法,则可以接收和处理事件和操作消息。 作为窗口对象或全局应用程序对象(AppKit中的NSApp
)的委托的自定义对象也可以接收和处理这些消息。
装饰器设计模式动态地将附加职责附加到对象上。 装饰器为子类提供了灵活的替代方案,以扩展功能。 与子类一样,修饰器模式的改编允许您合并新行为而无需修改现有代码。 装饰器包装其行为扩展的类的对象。 它们实现与包装对象相同的接口,并在将任务委派给包装对象之前或之后添加自己的行为。 装饰器模式表达了设计原则,即类应该对扩展开放,而对修改不开放。
可可如何适应装饰器设计模式?
代表团
委托是一种机制,主机对象通过该机制将对另一个对象(它的委托人)的弱引用(在某种意义上说是简单的指针引用,是弱的,未保留)嵌入,并在需要其任务输入时定期向该委托发送消息。 宿主对象通常是一个“现成的”框架对象(例如NSWindow
或NSXMLParser
对象),它试图完成某些任务,但只能以通用方式完成。 委托几乎总是一个自定义类的实例,该委托与宿主对象协同工作,在任务的某些位置提供特定于程序的行为(参见图1)。 因此,委派使得无需子类即可修改或扩展另一个对象的行为。
可可在其几个类的实现中使用Decorator模式,包括NSAttributedString
, NSScrollView
和UIDatePicker
。 后两个类是复合视图的示例,这些视图将其他视图类的简单对象组合在一起并协调它们的交互。
用途和局限性
授权是可可框架中的常见设计。 AppKit和UIKit框架中的许多类都将消息发送给委托,包括NSApplication
, UIApplication
, UITableView
和NSView
几个子NSView
。 Foundation框架中的某些类(例如NSXMLParser
和NSStream
)也维护委托。 除非委托方法不允许您实现目标,否则应始终使用类的委托机制而不是对类进行子类化。
尽管可以动态更改委托,但是一次只能有一个对象成为委托。 因此,如果您希望同时向多个对象通知特定的程序事件,则不能使用委托。
Facade设计模式为子系统中的一组接口提供了统一的接口。 该模式定义了一个更高级别的接口,该接口通过降低复杂性并隐藏子系统之间的通信和依赖性来使子系统更易于使用。
可可如何适应立面设计模式?
NSImage
AppKit框架的NSImage
类提供了一个统一的接口,用于加载和使用基于位图的图像(例如JPEG,PNG或TIFF格式的图像)或基于矢量的图像(例如EPS或PDF格式的图像)。 NSImage
可以保留同一图像的多个表示; 每个表示形式都是一种NSImageRep
对象。 NSImage
自动选择适合于特定类型的数据和给定显示设备的表示形式。 它还隐藏了图像处理和选择的细节,以便客户端可以互换使用许多不同的基础表示。
用途和局限性
由于NSImage
支持图像的几种不同表示,因此某些请求的属性可能不适用。 例如,如果基础图像表示基于矢量且与设备无关,则向图像询问像素的颜色将不起作用。