观察者模式
定义了对象之间的一种一对多的依赖关系,当一个对象(主题subject)改变状态时,它的所有依赖者(观察者observer)都会收到通知,并自动更新。
所谓一对多关系是指,主题是具有状态的对象,并可以控制状态,观察者使用状态,即使状态并不属于它们,许多观察者依赖主题来通知他们主题的状态何时或怎样改变了,从而产生一对多关系。
而依赖的产生是因为真正拥有数据的是主题,观察者依赖于主题,当数据变化时更新,相对于多个对象控制同一份数据,可以更容易实现一致性。
观察者模式主要工作是解耦和(decouple),使耦合双方依赖于抽象而不是具体(依赖倒置原则)。主题和观察者之间是松耦合。体现在:
- 主题仅依赖于实现观察者接口的对象列表,可随时增加或减少观察者而自身不受影响。
- 新增加的观察者不用改变主题的代码,只需在新类中实现观察者接口后注册为观察者,主题便可向它发送通知。
- 观察者和主题之间可独立复用,改变其中一方不会影响另一方,只要二者之间的接口仍被遵守即可。
在编程中,可以通过主题引用观察者,函数指针,委托,注册键值观察对事件进行通知。
例如在objective-c中,A view中包含有B view,B view要修改A view的界面,此时需要用到委托。那么首先要定义一个协议,A view实现其中的方法,B view设置一个委托变量,并设为A,即B view 委托A view完成一件事,此处,B是主题,A是观察者,当事件发生后,B view用委托变量调用A view中的协议方法,A view观察到B view的要求并产生响应。
B view.h
@protocal BViewDelegate <NSObject>
- (void)function;//声明协议方法
@end
@interface BView
{
id< BViewDelegate > _delegate; //设置委托变量
}
@property(nonatomic, assign) id< BViewDelegate > delegate;
@endBView.mm:
@synthesize delegate = _delegate;
- (void)init{
if (self = [super init]){
// Initialization code
_delegate = nil;
}
return self;
}
- (void)change
{
[_delegate function]; //调用协议委托
}
@endAView.h:
@interface AViewController : UIViewController < UIBViewDelegate >
{
BView *_bView;
}
@endAView.mm:
- (void)viewDidLoad
{
_bView.delegate = self; //设置委托
[self.view addSubview: _bView];[super viewDidLoad];
}
- (void)function
{
//实现协议
}
简单工厂模式
其本身并不是一种模式,而是一种编程习惯。
编程时,代码针对接口编写,通过多态可以与任何新类实现该接口,但如果代码实现大量具体的类时,一旦加入新的具体的类,则必须修改代码。
若将实例化具体类的代码从应用中抽离或封装起来,使之不会干扰应用的其他部分,则会用到工厂(封装创建对象的代码)。
简单工厂模式的主要工作就是将具体实例化的过程从客户代码中删除,并封装起来,除去了与具体产品的依赖。
工厂模式
定义了一个创建对象的接口,但是由子类决定要实例化的类是那一个,其中的工厂方法让类把实例化推迟到子类。
工厂方法用来处理对象的创建,并将这样的行为封装在子类中,这样客户程序中关于超类的代码和子类对象的创建代码就被解耦了,原本由一个对象负责所有具体的类的实例化变成由一群子类来负责实例化。
工厂方法在C++中体现未纯虚类,Java中表现为接口,objective-c中体现为协议,定义了一组方法,而不提供具体实现, 只有“遵守”或“采用”了Protocol的类会给出自己的实现。协议不是类本身,它们仅定义了其它对象有责任实现的接口。
优点:将创建对象的代码集中在一个对象或方法中,可避免代码的重复,并方便维护,而且客户在以后实例化对象时,依赖于接口而不是具体的类。
与简单工厂模式相比,简单工厂模式把全部的事情放在一个地方处理完毕,不具备工厂方法的弹性,比如不能更正正在创建的产品,而工厂模式由子类决定如何实例化,但每增加一个产品,都要添加该产品的工厂类,增加了额外开发量。
by xuejiang