在面向对象的编程中,子类化是增加应用程序特定行为的一种方法。但是过度子类化会使应用程序的结构不清晰、日后维护非常困难。 因此,一些基于设计模式的方法和技巧成为优化程序结构的一个非常好的选择。可用性和可扩展性是我们采用这些设计模式的主要目的。
一、最主要的设计模式:MVC(模型-视图-控制器)
该模式把一个应用程序分成了三个模块,定义了每个模块在应用程序中所扮演的角色以及他们之间如何通信。
模型:
模型对象封装应用程序的数据,并定义操控这些数据的方法。例如,一个模型对象封装了一架飞机的属性以及如何计算该飞机的攻击力的方法等等。数据模型的一大特点就是可以重复使用,当数据载入应用程序时,大部分的数据都应该驻留在数据模型中。
模型对象不可以直接与视图进行通讯,必须以控制器作为桥梁。
视图:
视图对象时用户可以看到的对象,它知道如何在屏幕上呈现自己并且可能与用户进行交互。视图的主要目的就是显示来自模型对象的数据。
控制器:
上面已经说了,控制器在MVC架构中充当的是桥梁、媒介的角色。通过它,模型对象和视图对象可以了解到各自的更改。
二、委托(delegate)
委托就是一个称为委托的对象A接受另一个对象B的请求并作为它的代表,也就是说B对象干不了的事要委托A对象来帮他干。B对象会向他的委托A发送消息,并要求他给出回应(也就是得到一个返回值)。因此委托是一个强大的设计模式,因为它无需创建子类就可以扩展该类的功能。
委托随处可见,当一个工程建立时,就可以看到自动创建的委托类AppDelegate,该类作为应用程序的委托负责处理应用程序所传来的消息。例如application:didFinishLaunchingWithOptions:
三、协议(protocal)
协议实际上就是一个接口类, 类似于C++/JAVA中的纯虚基类。遵循这个协议的类必须实现该协议中所要求实现的方法。因此,如果两个没有任何关系的类都遵循了同一个协议,那么他们就可以进行通讯,这也是替代子类化的一个方案
三、通知中心(NotificationCenter)
通知中心是NSNotificationCenter类的一个实例, 它能够广播一条通知发送给所有订阅了该通知的对象。在这里,这些对象作为 观察者(Observer). 通知发送给观察者,并要求观察者做出响应。例如应用程序的主视图如果订阅了UIApplicationWillEnterBackgroundNotification(应用程序进入后台)的通知,那么在应用程序进入后台时,它就能对此做出响应(performSelector)
四、目标-操作(Target-Action)
一个对象储存着组成消息表达式的元素,某些事件发生时,将这些元素放在一起,并发送一则消息。这些元素为一个选择器,用来确定消息(即操作)和接收消息的对象(即目标)。目标的类会实现与操作和目标相对应的方法,当它在运行中接收到消息时,会通过执行方法来响应事件。
例如在手势识别这一块:
UISwipeGestureRecognizer *vertical = [UISwipeGestureRecognizer alloc] initWithTarget:self action:@seletor(reportVerticalSwipe:)];
这是在视图控制器类中ViewDidLoad中的一行代码,声明了一个手势识别器,它把当前视图控制器(self)作为接收消息的对象,并响应一个方法
reportVerticalSwipe:
五、键-值观察(KVO)
键值观察(Key-value observing,或简称 KVO)允许对象观察另一个对象的属性。该属性值改变时,会通知观察对象。它了解新值以及旧值;如果观察的属性为对多的关系(例如数组),它也要了解哪个包含的对象发生了改变。KVO 有助于使应用程序变得更内聚,保持模型、控制器和视图层中的对象与改变同步。
六、响应者链(responder chain)
以UIResponder为基类的任何类都是响应者,UIView是UIResponder的子类,UIControl是UIView的子类,因此所有视图和所有控件都是响应者,他们响应系统所生成的事件如屏幕触摸。
如果第一个响应者不处理某个特殊事件(如某个手势),则它会将该事件传递到响应者链的下一级。如果该链中的下一个对象响应此特殊事件,则它通常会处理该事件,这将停止该事件沿着响应者链向前传递。
响应者链大多数情况下如下所示:
视图或控件——>>>视图控制器——>>>第一个响应者的父视图——>>>父视图的控制器......沿着视图的层次前进——>>>UIWindow——>>>UIApplication——>>>应用程序的委托——>>>事件被丢弃