【设计模式学习笔记二十二】【行为模式】【策略模式(Strategy)】

来源:互联网 发布:超链接执行js 编辑:程序博客网 时间:2024/06/02 01:07

本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:http://blog.csdn.net/lovelion/article/details/17517213

主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。

我应该理解和掌握的:

1)能够画出这个设计模式的架构框图;

2)能够根据架构框图写出对应的伪代码;

3)这个模式的应用场景,主要优缺点。

1.策略模式

条条大路通罗马,殊途同归,从某种程度上反应出策略模式,实现某一个功能有多条途径,每一条途径对应一种算法,此时我们可以使用这种设计模式来实现灵活的选择解决途径,也能够方便的增加新的解决途径。策略模式的主要目的是将算法的定义和使用分开,也就是将算法的行为和环境分开,将算法定义到专门的策略类中,每一个策略类封装了一种实现算法,使用算法的环境类针对抽象策略类进行编程,符合依赖倒转原则。出现新的算法时,只需要增加一个新的实现了抽象策略类的具体策略类即可。

(1)定义

策略模式:定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替换。本模式使得算法可独立于使用他的客户而变化。

1) 策略模式结构图


2) 参与者

a)Strategy(策略):定义所有支持的算法的公共接口。context使用这个接口来调用某ConcreteStrategy定义的算法。

b)ConcreteStrategy(具体策略):以Strategy接口实现某具体算法,运行时具体策略对象覆盖环境类的抽象策略对象。

c)Context(上下文):用一个ConcreteStrategy对象来配置;维护一个对Strategy对象的引用;可定义一个接口来让Strategy来访问他的数据。

3) 看图写代码

/*** FileName     : StrategyPattern** Author       : lin005** Date         : 2015/02/10** Description  : More information, please go to http://blog.csdn.net/amd123456789*/#include<iostream>using namespace std;//枚举变量,表示不同的策略算法enum STRATEGY{SA,//A算法SB //B算法};//抽象策略类class Strategy{public://声明策略类接口virtual void algorithm() = 0;};//具体策略类Aclass ConcreteStrategyA : public Strategy{public:ConcreteStrategyA(){}//定义自己的算法实现void algorithm(){cout<<"this is A algorithm!"<<endl;}};//具体策略类Bclass ConcreteStrategyB : public Strategy{public:ConcreteStrategyB(){}//定义自己的算法实现void algorithm(){cout<<"this is B algotithm!"<<endl;}};//上下文class Context{public://通过传入枚举类型,创建不同的具体策略Context(STRATEGY type){if(SA == type){p_strategy = new ConcreteStrategyA();}else if(SB == type){p_strategy = new ConcreteStrategyB();}else{cout<<"need add new strategy in concructor!"<<endl;}}~Context(){if(p_strategy){delete p_strategy;p_strategy = NULL;}}//调用创建的策略类方法void algorithm(){if(p_strategy){p_strategy->algorithm();}else{cout<<"no strategy in context->algorithm()!"<<endl;}}private://持有一个策略类对象Strategy* p_strategy;};//客户端测试程序#define SAFE_DELETE(p) if(p){delete p; p = NULL;}int main(){//创建一个上下文,通过传入类型选择不同的策略算法Context* c = new Context(SB);c->algorithm();return 0;}

(2)总结

1) 优点

a) 支持开闭原则,不修改原有代码也可以灵活的增加新的算法或行为。

b)提供了管理相关的算法族办法。使用继承把公共代码移到抽象策略类中,从而避免重复代码。

c)消除了一些条件语句,避免堆砌在一个上下文对象中。

d)提供了一种算法的复用机制。由于将算法单独提出出来封装在策略类中,不同的环境类可以方便的复用这些策略类。

2) 缺点

a)客户端必须了解不同的策略类,并自行决定使用哪一个策略类。

b)增加了对象数目,可能造成系统产生很多具体策略类。

c)无法在客户端同时使用多个策略类

(3)适用场景

1)许多相关的类仅仅是行为有异。策略提供了一种用多个行为中的一个行为来配置一个类的方法。

2)需要使用一个算法的不同变体

3)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现;将相关的条件分支移入他们各自的Strategy类中以代替这些条件语句。

4)算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。

5)一个系统需要动态的在几种算法中选择一种,那么可以将这些算法封装到一个个具体的算法类中,而这些具体算法类都是一个抽象算法类的子类。客户端可以选择使用任何一种算法,并只需要维持一个数据类型是抽象算法类的对象。

0 0
原创粉丝点击