【设计模式学习笔记二十二】【行为模式】【策略模式(Strategy)】
2015-02-10 08:42
716 查看
本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:/article/1610242.html
主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
b)ConcreteStrategy(具体策略):以Strategy接口实现某具体算法,运行时具体策略对象覆盖环境类的抽象策略对象。
c)Context(上下文):用一个ConcreteStrategy对象来配置;维护一个对Strategy对象的引用;可定义一个接口来让Strategy来访问他的数据。
b)
提供了管理相关的算法族办法。使用继承把公共代码移到抽象策略类中,从而避免重复代码。
c)
消除了一些条件语句,避免堆砌在一个上下文对象中。
d)
提供了一种算法的复用机制。由于将算法单独提出出来封装在策略类中,不同的环境类可以方便的复用这些策略类。
客户端必须了解不同的策略类,并自行决定使用哪一个策略类。
b)
增加了对象数目,可能造成系统产生很多具体策略类。
c)
无法在客户端同时使用多个策略类。
许多相关的类仅仅是行为有异。策略提供了一种用多个行为中的一个行为来配置一个类的方法。
2)
需要使用一个算法的不同变体。
3)
一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现;将相关的条件分支移入他们各自的Strategy类中以代替这些条件语句。
4)
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
5)
一个系统需要动态的在几种算法中选择一种,那么可以将这些算法封装到一个个具体的算法类中,而这些具体算法类都是一个抽象算法类的子类。客户端可以选择使用任何一种算法,并只需要维持一个数据类型是抽象算法类的对象。
主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。
我应该理解和掌握的:
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; }; //具体策略类A class ConcreteStrategyA : public Strategy { public: ConcreteStrategyA(){} //定义自己的算法实现 void algorithm() { cout<<"this is A algorithm!"<<endl; } }; //具体策略类B class 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)
一个系统需要动态的在几种算法中选择一种,那么可以将这些算法封装到一个个具体的算法类中,而这些具体算法类都是一个抽象算法类的子类。客户端可以选择使用任何一种算法,并只需要维持一个数据类型是抽象算法类的对象。
相关文章推荐
- 步步为营 .NET 设计模式学习笔记 三、Strategy(策略模式)
- 【设计模式】学习笔记1:策略模式(Strategy)
- 设计模式学习笔记(四):策略模式【Strategy】
- 步步为营 .NET 设计模式学习笔记 三、Strategy(策略模式)
- java 设计模式学习笔记十五 strategy 策略设计模式
- 设计模式学习笔记(六)之策略模式(Strategy)
- 设计模式学习笔记--策略(Strategy)模式
- 设计模式学习笔记(3)之策略设计模式(Strategy)
- 设计模式学习笔记二:Strategy,策略模式
- 设计模式学习笔记二十二——Strategy模式
- java 设计模式学习笔记十五 strategy 策略设计模式
- 设计模式学习笔记--Strategy 策略模式
- 步步为营 .NET 设计模式学习笔记 三、Strategy(策略模式)
- 设计模式 学习笔记 之 策略模式 Strategy(4)
- [学习笔记]Head First 设计模式 - 策略模式(Strategy)
- 设计模式学习笔记(六)之策略模式(Strategy)
- 设计模式学习笔记之(二、策略模式)
- Java设计模式(学习笔记)--Strategy 模式
- 设计模式学习—Strategy(策略)
- java 设计模式 学习笔记(4) 策略模式