可以看到 Strategy 模式和 Template 模式解决了类似的问题,也正如在 Template 模式中
分析的,Strategy模式和 Template 模式实际是实现一个抽象接口的两种方式:继承和组合之
间的区别。要实现一个抽象接口,继承是一种方式:我们将抽象接口声明在基类中,将具体
的实现放在具体子类中。组合(委托)是另外一种方式:我们将接口的实现放在被组合对象
中,将抽象接口放在组合类中。这两种方式各有优缺点,先列出来:
 继承:
„ 优点
1)易于修改和扩展那些被复用的实现。
„ 缺点
1)破坏了封装性,继承中父类的实现细节暴露给子类了;
2) “白盒”复用,原因在 1)中;
3)当父类的实现更改时,其所有子类将不得不随之改变
4)从父类继承而来的实现在运行期间不能改变(编译期间就已经确定了)

 组合 :
„ 优点
1) “黑盒”复用,因为被包含对象的内部细节对外是不可见的;
2)封装性好,原因为 1) ;
3)实现和抽象的依赖性很小(组合对象和被组合对象之间的依赖性小) ;
4)可以在运行期间动态定义实现(通过一个指向相同类型的指针,典型的是抽象
基类的指针) 。
„缺点
1)系统中对象过多。

从上面对比中我们可以看出,组合相比继承可以取得更好的效果,因此在面向对象
的设计中的有一条很重要的原则就是:优先使用(对象)组合,而非(类)继承(Favor Composition Over Inheritance)

 //////////////Strategy.h//////////////////////
#pragma once
class Strategy
{
public:
virtual ~Strategy();
Strategy();
virtual void AlgrithmInterface() = ;
protected:
private:
}; class ConcreteStrategyA : public Strategy
{
public:
~ConcreteStrategyA();
ConcreteStrategyA();
void AlgrithmInterface();
protected:
private:
}; class ConcreteStrategyB : public Strategy
{
public:
~ConcreteStrategyB();
ConcreteStrategyB();
void AlgrithmInterface();
protected:
private:
};
/////////////Strategy.cpp/////////////////////////////////////////////////
#include "Strategy.h"
#include <iostream>
using namespace std;
Strategy::~Strategy()
{
cout<<"~Strategy....."<<endl;
}
Strategy::Strategy()
{ } ConcreteStrategyA::~ConcreteStrategyA()
{
cout<<"~ConcreteStrategyA....."<<endl;
}
ConcreteStrategyA::ConcreteStrategyA()
{ }
void ConcreteStrategyA::AlgrithmInterface()
{
cout<<"test ConcreteStrategyA....."<<endl;
} ConcreteStrategyB::~ConcreteStrategyB()
{
cout<<"~ConcreteStrategyB....."<<endl;
}
ConcreteStrategyB::ConcreteStrategyB()
{ }
void ConcreteStrategyB::AlgrithmInterface()
{
cout<<"test ConcreteStrategyB....."<<endl;
}
///////////Context.h///////////////////////////
#pragma once
class Strategy ;
class Context
{
public:
~Context();
Context(Strategy* stg);
void DoAction();
protected:
private:
Strategy* _stg ;
};
//////////Context.cpp///////////////////////////////////
#include "Context.h"
#include "Strategy.h"
#include <iostream> Context::Context(Strategy* stg)
{
_stg = stg ;
} Context::~Context()
{
if (_stg != NULL)
{
delete _stg ;
}
} void Context::DoAction()
{
_stg->AlgrithmInterface();
}
/////////////main.cpp//////////////////////////////////
#include "Context.h"
#include "Strategy.h"
#include <iostream>
int main()
{
Strategy* ps = new ConcreteStrategyA();
Context* pc = new Context(ps);
pc->DoAction();
delete pc;
getchar();
return ;
}

Strategy 模式的更多相关文章

  1. 敏捷软件开发(4)--- TEMPLATE METHOD & STRATEGY 模式

    1.TEMPLATE METHOD 泛型,也就是这个模式,是可以基于泛型的. 我们往往会有一些算法,比如排序算法.它的算法部分,我可以把它放在一个基类里面,这样具体类型的比较可以放在子类里面. 看如下 ...

  2. 模板模式与策略模式/template模式与strategy模式/行为型模式

    模板模式 模版模式,又被称为模版方法模式,它可以将工作流程进行封装,并且对外提供了个性化的控制,但主流程外界不能修改,也就是说,模版方法模式中,将工作的主体架构规定好,具体类可以根据自己的需要,各自去 ...

  3. Template Method模式和Strategy模式[继承与委托]

    继承 program by difference. 通过继承,可以建立完整的软件结构分层.其中每一层都可以重用该层次以上的Code. 过度使用继承的代价是巨大的.应使用组合或者委托来替代继承. Tem ...

  4. 【行为型】Strategy模式

    策略模式意图将解决问题的算法分别封装成一个个对象的形式,并使这些算法对象相互间可被替换.模式比较简单,对于策略对象结构的设计,可抽象一个抽象基类,并定义好相关算法(纯)虚接口,并由各种具体的实现算法子 ...

  5. C++设计模式---Strategy模式

    一.前言 学习的第一个设计模式!不知道理解的对不对,期望大家一起多交流~ Strategy模式:策略模式,定义了算法族,分别封装起来,此模式可以让算法的变化独立于使用算法的客户.Strategy模式将 ...

  6. 设计模式之Singleton模式和Strategy模式是什么

    Singleton模式 单例模式,也交单子模式,有时候系统只需要拥有一个全局对象. 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建.这个类提供了一种访问其唯一的对象的方 ...

  7. Java设计模式(18)策略模式(Strategy模式)

    Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线, ...

  8. 设计模式之——浅谈strategy模式(策略模式)

    strategy模式,即策略模式.个人觉得吧,策略模式更多的是一种思维方式. 首先我们要知道,为什么需要策略模式.举个例子,比如用程序输出今天下午去玩什么. PlayGame 玩游戏 package ...

  9. 策略(strategy)模式

    Head First一书中对于策略(strategy)模式的正式定义是:策略模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户. 为了介绍这个算法,书中讲了 ...

随机推荐

  1. Poj 2528-Mayor's posters 线段切割

      题目:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total ...

  2. 使用NppExec插件让Notepad++编译运行Java、Python

    一直希望有一个轻量级的编辑器,既可以编辑代码,也可以一键运行.后来有了NotePad++,希望可以配置配置达到目的,配Java的时候上网搜了一堆,基本上互相抄,不解决实际问题,很郁闷.后来琢磨了出来, ...

  3. Quartz定时任务学习(四)调度器

    org.quartz.Scheduler 类层次 作为一个 Quartz 用户,你要与实现了 org.quartz.Scheduler 接口的类交互.在你调用它的任何 API 之前,你需要知道如何创建 ...

  4. Web缩放

    可以这么写,这个网页缩放了 同时滚动条也被绽放了,明显结果不正确 webBrowser1.Document.Body.Style = "zoom:200%"; 正解 http:// ...

  5. linux jdk tomcat

    linux jdk tomcat mysql的安装 mysql的话,推荐使用命令行安装,而不是用外部的源码去编译,因为简单粗暴. mysql服务:sudo apt-get install mysql- ...

  6. 为centos6.5系统添加epel源

    1.进去http://fedoraproject.org/wiki/EPEL 2.因为系统是centos 6.5,所以获取epel-release-latest-6.noarch.rpm的地址(htt ...

  7. [置顶] String StringBuffer StringBuilder的区别剖析

    这是一道很常见的面试题目,至少我遇到过String/StringBuffer/StringBuilder的区别:String是不可变的对象(final)类型,每一次对String对象的更改均是生成一个 ...

  8. 如何设计一个更好的C++ ORM

    2016/11/26 "用C++的方式读写数据库,简直太棒了!" 上一篇相关文章:如何设计一个简单的C++ ORM (旧版代码)

  9. sum() over() 函数的使用

    over不能单独使用,要和分析函数:rank(),dense_rank(),row_number(),sum()等一起使用. over函数的参数:over(partition by columnnam ...

  10. Android(java)学习笔记186:对ListView等列表组件中数据进行增、删、改操作

    1.ListView介绍 解决大量的相似的数据显示问题 采用了MVC模式: M: model (数据模型) V:  view  (显示的视图) C: controller 控制器 入门案例: acit ...