设计模式之策略模式

2016-03-23

策略模式

策略模式的定义

定义一些列算法,将每一个算法封装起来,并让它们可以相互替换,策略模式是让算法对于使用它的客户而变化,也称为政策模式。策略模式是一种对象行为模式,对象行为模式就是把行为看作面向对象的,是一种面向对象的思想,简单的理解就是,对象本身与算法使独立的,对象本身可以根据具体情况使用不同的算法(策略,具体行为)。

情景分析

情景1:把N种算法植入到同一段代码中,然互使用if-else 或者switch-case条件语句来决定要使用哪种算法?这些算法可能是相似的类函数或方法,用以解决相关的问题。

情景2:旅行出行方式,非常经典情景,不同的人要从A点到B点旅行,可以选择乘坐火车,汽车,飞机,骑自行车等。代码的实现一般都是通过if-else或者switch-case条件语句来决定不同人选择何种出行方式。

问题思考

思考:
1.如何消除根据不同的对象决定使用什么算法或者什么出行方式的 一大堆if-else或者switch-case的判断;
2.如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化。

解决方案

把每个算法封装成一个对象,就能解决以上两个问题,而 根据策略模式的定义,所以使用策略模式设计,此问题就会得到解决。策略模式的作用就是把对象本身与算法分开来,其功能非常强大,因为策略模式的核心思想就是面向对象编程的多形性思想。

小提示

这里的 “算法” 并不一定是指 真正意义的算法,换句话说,可以是真正意义的算法(冒泡排序,二分法,快速排序等),也可以是指不同的方式或者方法,行为,去实现相同的 目的或者产生同样的效应。”算法” 即 “策略”。

策略模式的结构

环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
抽象策略类(Strategy):定义所有支持的算法(策略)的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法(策略)。
具体策略类(ConcreteStrategy):以Strategy为接口具体实现某一算法(策略)。

策略模式的优缺点

优点:
1,策略模式提供了可以替换继承关系的方法
2,灵活选择不同的策略
3,消除了if-else或者switch-case判断
4,策略模式提供了管理相关算法簇的方法
缺点:
1,客户端需要具体知道有哪些具体策略
2,会产生很多策略类

策略模式适用性

1,一个对象需要动态的选择几种算法的一种
2,不希望客户端知道复杂的,与算法相关数据结构,在具体策略类中封装算法和数据机构,提供保密性和安全性
3,一个类操作中使用多个条件语句来定义许多行为

策略模式的实现

两种方式实现–继承与协议

在基类中,Person .h

1
2
3
4
5
6
7

#import <Foundation/Foundation.h>
#import <Transport.h>
@interface Person: NSObject
- (void)travelWithTransport:(Transport *)transport;
@end

Person.h

1
2
3
4
5
6
7

@implementation Person
- (void)travelWithTransport:(Transport *)transport{
[transport travel];
}
@end

Transport.h

1
2
3
4
5
6

#import <Foundation/Foundation.h>
@interface Transport:NSObject
- (void)travel; //子类去实现
@end

Transport.m

1
2
3
4

@implementation Transport
@end

//子类中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@interface Plane:Transport
@end

@implementation Plane
-(void)travel{

NSLog("by plane...");

}
@end

@interface Car:Transport
@end

@implementation Car
-(void)travel{

NSLog("by car...");

}
@end

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#import <Car.h>
#import <Plane.h>
#import <Person .h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Person *xiaoming = [[Person alloc]init];
[xiaoming travelWithTransport:[[Car alloc]init] ];
[xiaoming travelWithTransport:[Plane new]];
}
@end

总结

如有发现bugs,请联系`woodjobber@outlook.com`

项目地址:https://github.com/woodjobber/Design-Pattern-

微信公众号:嘀咕嘀咕(iOSSharers)

扫二维码关注