对象去耦,简单来说就是让对象之间没有依赖。涉及到对象去耦的有以下两种设计模式。其实,这两种设计模式都是靠把对象间的关联转移到第三者上(中介者和观察者)。
① 中介者
② 观察者
一. 中介者
中介者模式是用一个对象来封装一系列对象的交互方式。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立改变它们之间的交互。
面向对象的设计鼓励把行为分散到不同对象中,这种分散可能导致对象之间的相互关联,增加的关联使得对象很难或不能在不依赖其他对象的情况下工作。中介者模式用于定义一个集中的场所,对象之间的交互可以在一个中介者对象中处理。其他对象不必彼此交互,因此减少它们之间的依存关系。
抽象的Mediator定义了用于同Colleague交互的一般行为。典型的同事(colleague)是以明确定义的方式进行相互通信的对象,并且彼此紧密依存。ConcreteMediator为ConcreteColleague定义了更加具体的行为,因此可以子类化Mediator,把各种Colleague交互算法应用到相同或不同的Colleague类型。如果应用程序只需要一个中介者,有时抽象的Mediator可以省略。
Colleague的实例有一个Mediator实例的引用,同时Mediator的实例知道参与这个组织的每个对象。
中介者模式.png
举个例子🌰:我们常用到的导航栏控制器就是一个中介者,UINavigationController的实例被用一个根控制器初始化,根控制器把自己的视图提供给UINavigationController作为第一个视图。当需要迁移到另一个视图时,视图的所有者把它的控制器压入UINavigationController。然后UINavigationController会处理视图迁移的全部细节。UINavigationController管理内部的视图控制器栈,当前位于栈顶的试图控制器会显示在屏幕上,视图返回时,会从栈上弹出。
虽然中介者模式非常有用,但是应当注意避免中介者类过于庞大而难以维护。如果这样,可以考虑使用另一种设计模式把它分解。
在以下情形,需要考虑中介者模式:
- 对象间的交互虽定义明确然而非常复杂,导致一组对象彼此相互依赖难以理解。
- 因为对象引用了许多其他对象并非与其通讯,导致对象难以复用。
- 想要定制一个分布在多个类中的逻辑或行为,又不想生成太多子类。
二. 观察者
观察者模式,也叫发布-订阅模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
Observer从Subject订阅通知。ConcreteObserver实现抽象Observer并重载update方法。一旦Subject的实例需要通知Observer任何新的变更,Subject会发送update消息来通知存储在内部列表中所有注册的Observer。在ConcreteObserver的update方法的实际实现中,Subject的内部状态可被取得并在以后进行处理。
观察者模式.png以通知为例,NSNotificationCenter就是Subject,addObserver
的对象就是个Observer,它们会保存在NSNotificationCenter的一个集合中。当某对象postNotification
,NSNotificationCenter会让集合中的Observer去执行它们当初注册的方法,同时也可以取得它们想要的数据(anObject发送者和aUserInfo携带信息)。
// 发送通知
- (void)postNotificationName:(NSNotificationName)aName object:(nullable id)anObject userInfo:(nullable NSDictionary *)aUserInfo;
// 变成该通知的观察者,有通知就去处理
- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject;
在以下情形,需要考虑使用观察者模式:
- 有两种抽象类型相互依赖。将它们封装在各自的对象中,就可以对它们单独进行改变和复用。
- 对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
- 一个对象必须通知其他对象,而它又不需知道其他对象是什么。
网友评论