第28章 行为型模式大PK

27.1 策略模式 VS 命令模式

27.1.1 策略模式实现压缩算法

//行为型模式大PK——策略模式和命令模式
//实例:用策略模式实现压缩算法
#include <iostream>
#include <string>

using namespace std;

//抽象压缩算法
class Algorithm
{
public:
    //压缩算法
    virtual bool compress(string source, string to) = 0;
    //解压算法
    virtual bool uncompress(string source, string to) = 0;

    virtual ~Algorithm(){}
};

//具体算法:zip算法
class Zip : public Algorithm
{
public:
    //zip格式的压缩算法
    bool compress(string source, string to)
    {
        cout << source << " --> " << to <<" ZIP压缩成功" <<endl;
        return true;
    }
    //zip格式的解压缩算法
    bool uncompress(string source, string to)
    {
        cout << source <<" --> " << to <<" ZIP解压缩成功" <<endl;
        return true;
    }
};

//具体算法:Gzip
class Gzip : public Algorithm
{
public:
    //gzip格式的压缩算法
    bool compress(string source, string to)
    {
        cout << source << " --> " << to <<" GZIP压缩成功" <<endl;
        return true;
    }
    //gzip格式的解压缩算法
    bool uncompress(string source, string to)
    {
        cout << source <<" --> " << to <<" GZIP解压缩成功" <<endl;
        return true;
    }
};

//环境角色
class Context
{
private:
    Algorithm* al; //指向抽象算法
public:
    Context(Algorithm* al)
    {
        this->al = al;
    }

    //设置算法策略
    void setAlgorithm(Algorithm* al)
    {
        this->al = al;
    }

    //执行压缩算法
    bool compress(string source, string to)
    {
        return al->compress(source ,to);
    }

    //执行解压缩算法
    bool uncompress(string source, string to)
    {
        return al->uncompress(source ,to);
    }
};

int main()
{
    //创建两种算法策略
    Algorithm* alZip = new Zip();
    Algorithm* alGzip = new Gzip();

    //创建环境角色,并执行zip算法
    Context ctx(alZip);

    cout <<"========执算zip算法========" << endl;
    //执行压缩算法
    ctx.compress("c:\\window", "d:\\windows.zip");
    //执行解压缩算法
    ctx.compress("c:\\window.zip", "d:\\windows");

    //"========执算gzip算法========"
    cout <<"========执算gzip算法========" << endl;
    //更换算法
    ctx.setAlgorithm(alGzip);

    //执行压缩算法
    ctx.compress("c:\\window", "d:\\windows.zip");
    //执行解压缩算法
    ctx.compress("c:\\window.zip", "d:\\windows");

    delete alZip;
    delete alGzip;
    return 0;
};
/*输出结果:
========执算zip算法========
c:\window --> d:\windows.zip ZIP压缩成功
c:\window.zip --> d:\windows ZIP压缩成功
========执算gzip算法========
c:\window --> d:\windows.zip GZIP压缩成功
c:\window.zip --> d:\windows GZIP压缩成功
*/

27.1.2 命令模式实现压缩算法


注意:图中的接收者是按功能设计的

//行为型模式大PK——策略模式和命令模式
//实例:用命令模式实现压缩算法
#include <iostream>
#include <string>

using namespace std;

//抽象接收者
class IReceiver
{
public:
    //压缩
    virtual bool compress(string source, string to) = 0;
    //解压
    virtual bool uncompress(string source, string to) = 0;

    virtual ~IReceiver(){}
};

//zip接收者
class ZipReceiver : public IReceiver
{
public:
    //压缩
    bool compress(string source, string to)
    {
        cout << source << " --> " << to <<" ZIP压缩成功" <<endl;
        return true;
    }
    //解压
    bool uncompress(string source, string to)
    {
        cout << source << " --> " << to <<" ZIP解压缩成功" <<endl;
        return true;
    }
};

//Gzip接收者
class GzipReceiver : public IReceiver
{
public:
    //压缩
    bool compress(string source, string to)
    {
        cout << source << " --> " << to <<" GZIP压缩成功" <<endl;
        return true;
    }
    //解压
    bool uncompress(string source, string to)
    {
        cout << source << " --> " << to <<" GZIP解压缩成功" <<endl;
        return true;
    }
};

//抽象压缩命令
class AbstractCmd
{
protected:
    //持有接收者的引用
    IReceiver* zip;
    IReceiver* gzip;
public:
    AbstractCmd()
    {
        zip = new ZipReceiver();
        gzip = new GzipReceiver();
    }
    virtual ~AbstractCmd()
    {
        delete zip;
        delete gzip;
    }

    //抽象方法,命令的具体单元
    virtual bool execute(string source, string to) = 0;
};

//zip压缩命令
class ZipCompressCmd : public AbstractCmd
{
public:
    bool execute(string source, string to)
    {
        return  zip->compress(source, to);
    }
};

//zip解压缩命令
class ZipUncompressCmd : public AbstractCmd
{
public:
    bool execute(string source, string to)
    {
       return  zip->uncompress(source, to);
    }
};

//gzip压缩命令
class GzipCompressCmd : public AbstractCmd
{
public:
    bool execute(string source, string to)
    {
       return  gzip->compress(source, to);
    }
};

//gzip解压缩命令
class GzipUncompressCmd : public AbstractCmd
{
public:
    bool execute(string source, string to)
    {
       return  gzip->uncompress(source, to);
    }
};

//调用者
class Invoker
{
private:
    //持有抽象命令的引用
    AbstractCmd* cmd;
public:
    Invoker(AbstractCmd* cmd)
    {
        this->cmd = cmd;
    }

    //执行命令
    bool execute(string source, string to)
    {
        return cmd->execute(source, to);
    }

    void setCommand(AbstractCmd* cmd)
    {
        this->cmd = cmd;
    }
};

int main()
{
    //定义一个命令,压缩一个文件
    AbstractCmd* cmd = new ZipCompressCmd();
    //AbstractCmd* cmd = new ZipUncompressCmd();//换命令

    //定义调用者
    Invoker* invoker = new Invoker(cmd);
    //执行压缩命令
    cout <<"========执行压缩命令========"<<endl;

    invoker->execute("c:\\windows", "d:\\windows.zip");

    return 0;
};
/*输出结果:
========执行压缩命令========
c:\windows --> d:\windows.zip ZIP压缩成功
*/

//另一种实现(只提供类图)

注意:图中的接收者是按对象设计的

27.1.3 小结

(1)当命令模式退化时,比如无接收者(接收者非常简单,无需专门编写一个接收者),在这种情况下,命令模式和策略模式的类图完全一样,代码实现也比较类似

(2)关注点不同

  ①策略模式关注的是算法替换的问题,一个新的算法投产,旧算法退体,或者提供多种算法由调用者自己选择使用,算法的自由更替是它实现的要点。换句话说,策略模式关注的是算法的完整性、封装性,只有具备了这两个条件才能保证其可以自由切换。

  ②命令模式则关注的是解耦问题,如何让请求者和执行者解耦是它需要首先解决的,解耦的要求就是把请求的内容封装为一个个命令,由接收者执行。由于封装成命令,就同时可以对命令进行多种处理,例如撤销、记录等。

(3)角色功能不同

  ①策略模式中的具体算法是负责一个完整算法逻辑,它是不可再拆分的原子业务,一旦变更就是对算法整体的变更。

  ②命令模式关注命令的实现,也就是功能的实现。接收者对命令负责,而与请求者无关。

(4)使用场景不同

  策略模式适用于算法要求变换的场景,而命令模式适用于解耦两个有紧耦合的对象。

时间: 2024-10-17 10:47:47

第28章 行为型模式大PK的相关文章

第26章 创建型模式大PK

26.1 工厂方法模式 VS 建造者模式 26.1.1 按工厂方法建造超人 (1)产品:两类超人,成年超人和未成年超人. (2)工厂:这里选择简单工厂 [编程实验]工厂方法建造超人 //创建型模式大PK——工厂方法和建造者模式 //实例:利用简单工厂创建的超人 #include <iostream> using namespace std; //***************************抽象产品接口********************* //超人接口 class ISuperM

第27章 结构型模式大PK

27.1 代理模式 VS 装饰模式 27.1.1 代理模式 (1)场景:客人找运动员代理要求安排运动员参加比赛 (2)说明:代理人有控制权,可以拒绝客人的要求,也可以答应安排,甚至自己下去跑(因为有些运动员本身就作自己的代理) [编程实验]找代理安排运动员比赛 //创建型模式大PK——代理模式和装饰模式 //实例:找代理安排运动员比赛 #include <iostream> #include <ctime> using namespace std; //抽象运动员 class IR

设计模式之行为类模式大PK

                                    行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略模式.模板方法模式.访问者模式.该组设计模式众多,如下我们着重介绍一下命令模式VS策略模式.状态模式VS策略模式.观察者模式VS责任链模式. 命令模式VS策略模式 命令模式和策略模式类图很相似,只是命令模式多了一个接收者(Receiver)角色,通过确切的Command类调用Receiver类,实现

第5章 创建型模式—抽象工厂模式

1. 抽象工厂的定义 (1)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类 ①只需各要知道创建一系列对象的接口,而无需知道具体使用的是哪一个实现 ②这一系列对象是相关或相互依赖的,也就是说既要创建对象,还要约束它们之间的关系. ③一系列对象是构建新对象所需要的组成部分,并且对象之间相互有约赖.如电脑由CPU和主板等组成,但CPU的针脚数和主板提供的插口必须是匹配的,否则无法组装. (2)产品族和产品等级 ①产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等

第23章 行为型模式—策略模式

1. 状态模式(State Pattern)的定义 (1)定义:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. ①算法是同一接口的不同实现,地位是平等的,可以相互替换. ②引入上下文对象,可以实现让算法能独立使用它的客户.因为这个对象负责持有算法,但不负责决定具体选用哪个算法,把选择算法的功能交给了客户. ③当客户通知上下文对象执行功能的时候,上下文会转调具体的算法. (2)策略模式的结构和说明 ①Strategy:策略接口,用来约束一系

第24章 行为型模式—模板方法模式

1. 模板方法模式(Template Method Pattern)的定义 (1)定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. (2)模板方法模式的结构和说明 ①AbstractClass:抽象类.用于定义算法骨架和抽象的原语操作,具体的子类通过重定义这些原语操作来实现一个算法的各个步骤.在这个类里面,还可以提供算法中通用的实现.此外,该类还实现了一个模板方法,它定义了算法的骨架.该模板方法不仅调用原语操作,

第17章 行为型模式—解释器模式

1. 解释器模式(Interpreter Pattern)的定义 (1)定义 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. ①文法:即语法规则.在解释器模式中每一个语法都将对应一个解释器对象,用来处理相应的语法规则.它对于扩展.改变文法以及增加新的文法规则都很方便. ②解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子. ③在解释器模式中可以通过一种称之为抽象语法树(Abstract Syntax T

第16章 行为型模式—命令模式

1. 命令模式(Command Pattern)的定义 (1)定义 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. ①封装请求:抽象出需要执行的动作,封装成对象(有统一的接口). ②参数化:可以用不同的命令对象,去参数化配置客户的请求.(即,将命令对象作为参数去供Invoker调用). (2)命令模式的结构和说明 ①Command:定义命令的接口,声明执行的方法 ②ConcreteCommand:命令接口实现对象,是“虚”的实现

第4章 创建型模式—工厂方法模式(2)

2. 工厂方法模式 2.1工厂方法模式的定义 (1)定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类 ①Product:定义了工厂方法创建对象的接口.也就是实际需要使用的产品对象的接口 ②ConcreteProduct:具体的Product接口的实现对象. ③Factory(Creator):定义了工厂方法的抽象类并返回一个产品对象. ④ConcreteCreator:具体的创建器对象,该类实现和覆盖了父工厂类声明的方法.返回一个具体的Product实例