这次介绍一下策略模式(Strategy Pattern)
,相比之下是一种比较简单的模式。它也叫政策模式(Policy Pattern)
。
策略模式
使用的就是面向对象的继承
和多态
机制,其他的没有什么玄机。策略模式
适合使用在:
1. 多个类只有在算法或行为上稍有不同的场景。
2. 算法需要自由切换的场景。
3. 需要屏蔽算法规则的场景。
使用策略模式
当然也有需要注意的地方,那么就是策略类不要太多,如果一个策略家族的具体策略数量超过4个,则需要考虑混合模式
,解决策略类膨胀和对外暴露问题。在实际项目中,我们一般通过工厂方法模式
来实现策略类的声明。
下面我们就来具体讲解一下策略模式
。
策略模式定义
Define a family of algorithms, encapsulate each one, and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且是它们之间可以互换。)
策略模式类图
策略模式说明
Context封装角色
它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在变化。
Strategy抽象策略角色
策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
ConcreteStrategy具体策略角色
实现抽象策略中的操作,该类含有具体的算法。
策略模式优点
算法可以自由切换。
避免使用多重条件判断。
扩展性良好。
策略模式缺点
策略类数量增多
每一个策略都是一个类,复用的可能性很小,类数量增多。
所有的策略类都需要对外暴露
上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则
是相违背的。
策略模式的objective-C实现
Strategy
1
2
3
4
5
6
7
#import <Foundation/Foundation.h>
//定义接口
@protocol TransportStrategy < NSObject >
- ( void ) travelling ;
@end
ConcreteStrategy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#import <Foundation/Foundation.h>
#import "TransportStrategy.h"
@interface Car : NSObject < TransportStrategy >
@end
@implementation Car
- ( void ) travelling
{
NSLog ( @"travelling by car." );
}
@end
@interface Bicycle : NSObject < TransportStrategy >
@end
@implementation Bicycle
- ( void ) travelling
{
NSLog ( @"travelling by bicycle." );
}
@end
@interface Train : NSObject < TransportStrategy >
@end
@implementation Train
- ( void ) travelling
{
NSLog ( @"travelling by train." );
}
@end
Context
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#import <Foundation/Foundation.h>
#import "TransportStrategy.h"
@interface Person : NSObject
- ( void ) travel: ( id < TransportStrategy > ) transport ;
@end
@implementation Person
- ( void ) travel: ( id < TransportStrategy > ) transport
{
[ transport travelling ];
}
@end
main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#import <Foundation/Foundation.h>
#import "Car.h"
#import "Bicycle.h"
#import "Train.h"
#import "Person.h"
int main ( int argc , const char * argv [])
{
@autoreleasepool {
Car * car = [[ Car alloc ] init ];
Bicycle * bicycle = [[ Bicycle alloc ] init ];
Train * train = [[ Train alloc ] init ];
Person * person = [[ Person alloc ] init ];
[ person travel : car ];
[ person travel : bicycle ];
[ person travel : train ];
}
return 0 ;
}