装饰模式:
给原有的对象添加新的功能,但不继承原有的类。
Cocoa 中 Category 就属于这种设计模式。
举例:实现一个线程安全的数组
模板/原型模式:
某个对象,它的构成/创建十分复杂,可以考虑这种模式。
Cocoa 中 NSCoping 就属于这种模式。
举例: 假设有一个类 Model,它里面有 100 个属性 property1 ~ property100。有个对象 model1,这些属性都已经复制。现在如果需要一个 model2 和 model3 ,它们都与 model1 只有一个属性的值是不同的,那么有一种做法就是 把生成 model1 的 101 行代码复制粘贴两次再修改一下。 还有一种做法,在 Model 类中加一个方法:- (Model *)clone;
,然后实现 clone
:
- (Model *)clone {
Model *model = [[self class] init];
model.property1 = self.property1;
...
model.property100 = self.property100;
return model;
}
复制代码
这样我们创建其它 model 的时候就可以这样做:
Model *model2 = [model1 clone];
model2.propertyN = xxx;
复制代码
NSCopying 就是这样的。NSCopying 协议使用的时候要注意以下问题,假设 Person 类是这样的:
修改之后,看下面这段代码的输出:
person.sons 与 person2.sons 是两个不同的数组了。但是里面的元素却是相同的。这里就牵涉到几个比较绕的概念了:
- 浅拷贝
- 单层拷贝/单层深拷贝/深拷贝
- 完全拷贝(可以用归档来处理)
感兴趣的话可以自己搜一下。现在我们这种情况属于第二种。
外观/Facade模式(可以解耦)
先举个例子:假设我们要从西安去北京,可以选择自驾/坐飞机/坐火车等方式,都可以去,可以理解为通过不同的手段达到同一个目的,但是细节不同,但是我们不关心它的细节,只关心它的目的。
外观模式使用场景:
有一个复杂的子系统,它为了得到某种结果,里面有很多复杂的逻辑,客户端只想要这个结果,并不关心里面复杂的逻辑。可以写一个中间类,操作这个子系统,客户端只用从中间类来获取结果即可。
外观模式的好处:
解耦合
简化操作
外观模式与适配器模式的区别:
外观模式 -- 意图提供简单的接口
适配器模式 -- 转换接口
举例:
假设我们有一个 Shape 类,和他的一些子类们:
@interface Shape : NSObject
- (void)draw;
@end
****************************************
@interface Rectangle : Shape
@property (assign, nonatomic) CGFloat width;
@property (assign, nonatomic) CGFloat height;
@end
@implementation Rectangle
- (void)draw
{
绘制一个矩形;
}
@end
****************************************
@interface Circle : Shape
@property (assign, nonatomic) CGFloat radius;
@end
@implementation Circle
- (void)draw
{
绘制一个圆形;
}
@end
复制代码
假设我们在 ViewController 中写了如下代码:
- (void)viewDidLoad
{
[super viewDidLoad];
//绘制一个矩形
Rectangle *tangle = [[Rectangle alloc] init];
tangle.width = 10;
tangle.height = 20;
[tangle draw];
//绘制一个圆形
Circle *cir = [[Circle alloc] init];
cir.radius = 5;
[cir draw];
}
复制代码
如果 Shape 有多个子类,比如平行四边形、梯形、八边形等。那么它会是一个特别复杂的系统,并且我们还需要知道这个系统的细节,把数据具体地传递到每个对象对应的属性上才可以。
但其实上我们并不关心在这个系统中它们是怎么实现的,我们就只想让它画个图形就 OK 了。这是可以这么做,创建一个中间类 ShapeMaker:
@interface ShapeMaker : Shape
- (void)drawRectangleWithParams:(NSDictionary *)dic;
- (void)drawCircleWithParams:(NSDictionary *)dic;
- (void)drawRectangleAndCircleWithParams:(NSDictionary *)dic;
...
@end
复制代码
在 ShapeMaker 中去实现这些复杂的操作,ShapeMaker 提供一些简单的接口供 ViewController 使用,ViewController 只用使用接口,传递数据即可,ViewController 并不关心具体实现,也不知道具体每个数据用在哪个地方,它只是让 ShapeMaker 画个形状就可以了。