Head First命令模式qt

类图

在这里插入图片描述
在这里插入图片描述

定义

将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其它对象。命令模式也支持可撤销的操作

优缺点

优点:

1.降低对象之间的耦合度。
2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
4.调用同一方法实现不同的功能

缺点:

使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

适用环境:

1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。

设计原则

多用组合,少用继承
针对接口编程,不针对实现编程
对交互对象之间松耦合设计而努力
类应该对扩展开放,对修改关闭
依赖抽象,不要依赖具体类

代码

RemoteControlWithUndo类:

#ifndef REMOTECONTROLWITHUNDO_H
#define REMOTECONTROLWITHUNDO_H

#include "command.h"
#include "nocommand.h"

#include <QVector>

class RemoteControlWithUndo
{
public:
    RemoteControlWithUndo();

    void setCommand(int slot, Command *onCommand, Command *offCommand);
    void onButtonWasPushed(int slot);
    void offButtonWasPushed(int slot);
    void undoButtonWasPushed();

    QString toString();

    QVector<Command *> onCommands;
    QVector<Command *> offCommands;
    Command *undoCommand;
};

#endif // REMOTECONTROLWITHUNDO_H

#include "remotecontrolwithundo.h"

RemoteControlWithUndo::RemoteControlWithUndo()
{
    Command *noCommand1 = new NoCommand();
    Command *noCommand2 = new NoCommand();
    Command *noCommand3 = new NoCommand();

    onCommands.append(noCommand1);
    onCommands.append(noCommand2);
    onCommands.append(noCommand3);

    Command *noCommand4 = new NoCommand();
    Command *noCommand5 = new NoCommand();
    Command *noCommand6 = new NoCommand();

    offCommands.append(noCommand4);
    offCommands.append(noCommand5);
    offCommands.append(noCommand6);

    Command *noCommand7 = new NoCommand();
    undoCommand = noCommand7;
}

void RemoteControlWithUndo::setCommand(int slot, Command *onCommand, Command *offCommand)
{
    onCommands[slot] = onCommand;
    offCommands[slot] = offCommand;
}

void RemoteControlWithUndo::onButtonWasPushed(int slot)
{
    if(onCommands.at(slot) != nullptr) {
        onCommands.at(slot)->execute();
        undoCommand = onCommands[slot];
    }
}

void RemoteControlWithUndo::offButtonWasPushed(int slot)
{
    if(offCommands.at(slot) != nullptr) {
        offCommands.at(slot)->execute();
        undoCommand = offCommands[slot];
    }
}

void RemoteControlWithUndo::undoButtonWasPushed()
{
    undoCommand->undo();
}

QString RemoteControlWithUndo::toString()
{
    QString stringBuff;
    stringBuff = "---------- Remote Control ----------/n";
    for(int i = 0; i < onCommands.size(); i++) {
        stringBuff += "[slot " + QString::number(i) +"] " +
                onCommands.at(i)->getName() + "     " +
                offCommands.at(i)->getName() + "/n";
    }
    return stringBuff;
}

RemoteConrol类:

#ifndef REMOTECONROL_H
#define REMOTECONROL_H

#include "command.h"
#include "nocommand.h"

#include <QVector>

class RemoteConrol
{
public:
    RemoteConrol();
    void setCommand(int slot, Command *onCommand, Command *offCommand);
    void onButtonWasPushed(int slot);
    void offButtonWasPushed(int slot);

    QString toString();

    QVector<Command *> onCommands;
    QVector<Command *> offCommands;

};

#endif // REMOTECONROL_H
#include "remoteconrol.h"

RemoteConrol::RemoteConrol()
{
    Command *noCommand1 = new NoCommand();
    Command *noCommand2 = new NoCommand();
    Command *noCommand3 = new NoCommand();

    onCommands.append(noCommand1);
    onCommands.append(noCommand2);
    onCommands.append(noCommand3);

    Command *noCommand4 = new NoCommand();
    Command *noCommand5 = new NoCommand();
    Command *noCommand6 = new NoCommand();

    offCommands.append(noCommand4);
    offCommands.append(noCommand5);
    offCommands.append(noCommand6);


}

void RemoteConrol::setCommand(int slot, Command *onCommand, Command *offCommand)
{
    onCommands[slot] = onCommand;
    offCommands[slot] = offCommand;
}

void RemoteConrol::onButtonWasPushed(int slot)
{
    if(onCommands.at(slot) != nullptr) {
        onCommands.at(slot)->execute();
    }
}

void RemoteConrol::offButtonWasPushed(int slot)
{
    if(offCommands.at(slot) != nullptr) {
        offCommands.at(slot)->execute();
    }
}

QString RemoteConrol::toString()
{
    QString stringBuff;
    stringBuff = "---------- Remote Control ----------/n";
    for(int i = 0; i < onCommands.size(); i++) {
        stringBuff += "[slot " + QString::number(i) +"] " +
                onCommands.at(i)->getName() + "     " +
                offCommands.at(i)->getName() + "/n";
    }
    return stringBuff;
}

SimpleRemoteControl类:

#ifndef SIMPLEREMOTECONTROL_H
#define SIMPLEREMOTECONTROL_H

#include "command.h"

class SimpleRemoteControl
{
public:
    SimpleRemoteControl();
    void setCommandControl(Command* command);
    void buttonWasPressed();

    Command* slot;
};

#endif // SIMPLEREMOTECONTROL_H

#include "simpleremotecontrol.h"

SimpleRemoteControl::SimpleRemoteControl()
{

}

void SimpleRemoteControl::setCommandControl(Command* command)
{
    slot = command;
}

void SimpleRemoteControl::buttonWasPressed()
{
    slot->execute();
}

Command类:

#ifndef COMMAND_H
#define COMMAND_H

#include <QString>

class Command
{
public:
    virtual void execute() = 0;
    virtual void undo() = 0;

    virtual QString getName();
    QString name;
};

#endif // COMMAND_H
#include "command.h"

QString Command::getName()
{
    return name;
}

NoCommand类:

#ifndef NOCOMMAND_H
#define NOCOMMAND_H

#include "command.h"

class NoCommand : public Command
{
public:
    NoCommand();
    void execute() override;
    void undo() override;
};

#endif // NOCOMMAND_H

#include "nocommand.h"

NoCommand::NoCommand()
{

}

void NoCommand::execute()
{

}

void NoCommand::undo()
{

}


Light类:

#ifndef LIGHT_H
#define LIGHT_H

#include <QString>

class Light
{
public:
    Light(QString name);
    void on();
    void off();

private:
    QString name;
};

#endif // LIGHT_H

#include "light.h"

#include <QDebug>

Light::Light(QString name)
{
    this->name = name;
}

void Light::on()
{
    qDebug() << name + "Light is on";
}

void Light::off()
{
    qDebug() << name + "Light is off";
}

LightOffCommand 类:

#ifndef LIGHTOFFCOMMAND_H
#define LIGHTOFFCOMMAND_H

#include "command.h"
#include "light.h"

class LightOffCommand : public Command
{
public:
    LightOffCommand(Light* light);
    void execute() override;
    void undo() override;

private:
    Light* light;
};

#endif // LIGHTOFFCOMMAND_H

#include "lightoffcommand.h"

LightOffCommand::LightOffCommand(Light* light)
{
    this->light = light;
    name = "light";
}

void LightOffCommand::execute()
{
    light->off();
}

void LightOffCommand::undo()
{
    light->on();
}

LightOnCommand类:

#ifndef LIGHTONCOMMAND_H
#define LIGHTONCOMMAND_H

#include "command.h"
#include "light.h"

class LightOnCommand : public Command
{
public:
    LightOnCommand(Light* light);
    void execute() override;
    void undo() override;

    Light* light;
};

#endif // LIGHTONCOMMAND_H

#include "lightoncommand.h"

LightOnCommand::LightOnCommand(Light* light)
{
    this->light = light;
    name = "light";
}

void LightOnCommand::execute()
{
    light->on();
}

void LightOnCommand::undo()
{
    light->off();
}

Stereo类:

#ifndef STEREO_H
#define STEREO_H

#include <QString>

class Stereo
{
public:
    Stereo(QString name);
    void on();
    void off();
    void setCD();
    void setVolume(int volume);

private:
    QString name;
};

#endif // STEREO_H
#include "stereo.h"

#include <QDebug>

Stereo::Stereo(QString name)
{
    this->name = name;
}

void Stereo::on()
{
    qDebug() << name + "Stereo is on";
}

void Stereo::off()
{
    qDebug() << name + "Stereo is off";
}

void Stereo::setCD()
{
    qDebug() << name + "Stereo is setCD";

}

void Stereo::setVolume(int volume)
{
    qDebug() << name + "Stereo volume set to " + QString::number(volume);

}

StereoOffCommand 类:

#ifndef STEREOOFFCOMMAND_H
#define STEREOOFFCOMMAND_H

#include "command.h"
#include "stereo.h"

class StereoOffCommand : public Command
{
public:
    StereoOffCommand(Stereo *stereo);
    void execute() override;
    void undo() override;

private:
    Stereo *stereo;
};

#endif // STEREOOFFCOMMAND_H

#include "stereooffcommand.h"

StereoOffCommand::StereoOffCommand(Stereo *stereo)
{
    this->stereo = stereo;
    name = "stereo";
}

void StereoOffCommand::execute()
{
    stereo->off();
}

void StereoOffCommand::undo()
{
    stereo->on();

}

StereoOnWithCDCommand 类:

#ifndef STEREOONWITHCDCOMMAND_H
#define STEREOONWITHCDCOMMAND_H

#include "command.h"
#include "stereo.h"

class StereoOnWithCDCommand : public Command
{
public:
    StereoOnWithCDCommand(Stereo *stereo);
    void execute() override;
    void undo() override;

private:
    Stereo *stereo;
};

#endif // STEREOONWITHCDCOMMAND_H

#include "stereoonwithcdcommand.h"

StereoOnWithCDCommand::StereoOnWithCDCommand(Stereo *stereo)
{
    this->stereo = stereo;
    name = "stereo";
}

void StereoOnWithCDCommand::execute()
{
    stereo->on();
    stereo->setVolume(11);
}

void StereoOnWithCDCommand::undo()
{
    stereo->off();
}

CeilingFan类:

#ifndef CEILINGFAN_H
#define CEILINGFAN_H

#include <QString>

class CeilingFan
{
public:
    CeilingFan(QString location);
    void high();
    void medium();
    void low();
    void off();
    int getSpeed();

    QString location;
    int speed;
    const int HIGH = 3;
    const int MEDIUM = 2;
    const int LOW = 1;
    const int OFF = 0;

};

#endif // CEILINGFAN_H

#include "ceilingfan.h"

#include <QDebug>

CeilingFan::CeilingFan(QString location)
{
    this->location = location;
}

void CeilingFan::high()
{
    speed = HIGH;
    qDebug() << location + "CeilingFan is high";
}

void CeilingFan::medium()
{
    speed = MEDIUM;
    qDebug() << location + "CeilingFan is medium";
}

void CeilingFan::low()
{
    speed = LOW;
    qDebug() << location + "CeilingFan is low";
}

void CeilingFan::off()
{
    speed = OFF;
    qDebug() << location + "CeilingFan is off";
}

int CeilingFan::getSpeed()
{
    return speed;
}

CeilingFanHighCommand 类:

#ifndef CEILINGFANHIGHCOMMAND_H
#define CEILINGFANHIGHCOMMAND_H

#include "command.h"
#include "ceilingfan.h"

class CeilingFanHighCommand : public Command
{
public:
    CeilingFanHighCommand(CeilingFan *ceilingFan);
    void execute() override;
    void undo() override;

private:
    CeilingFan *ceilingFan;
    int prevSpeed;
};

#endif // CEILINGFANHIGHCOMMAND_H

#include "ceilingfanhighcommand.h"

CeilingFanHighCommand::CeilingFanHighCommand(CeilingFan *ceilingFan)
{
    this->ceilingFan = ceilingFan;
}

void CeilingFanHighCommand::execute()
{
    prevSpeed = ceilingFan->getSpeed();
    ceilingFan->high();
}

void CeilingFanHighCommand::undo()
{
    if(prevSpeed == ceilingFan->HIGH) {
        ceilingFan->high();
    } else if(prevSpeed == ceilingFan->MEDIUM) {
        ceilingFan->medium();
    } else if(prevSpeed == ceilingFan->LOW) {
        ceilingFan->low();
    } else if(prevSpeed == ceilingFan->OFF) {
        ceilingFan->off();
    }
}

CeilingFanLowCommand 类:

#ifndef CEILINGFANLOWCOMMAND_H
#define CEILINGFANLOWCOMMAND_H

#include "command.h"
#include "ceilingfan.h"

class CeilingFanLowCommand : public Command
{
public:
    CeilingFanLowCommand(CeilingFan *ceilingFan);
    void execute() override;
    void undo() override;

private:
    CeilingFan *ceilingFan;
    int prevSpeed;
};

#endif // CEILINGFANLOWCOMMAND_H

#include "ceilingfanlowcommand.h"

CeilingFanLowCommand::CeilingFanLowCommand(CeilingFan *ceilingFan)
{
    this->ceilingFan = ceilingFan;
}

void CeilingFanLowCommand::execute()
{
    prevSpeed = ceilingFan->getSpeed();
    ceilingFan->low();
}

void CeilingFanLowCommand::undo()
{
    if(prevSpeed == ceilingFan->HIGH) {
        ceilingFan->high();
    } else if(prevSpeed == ceilingFan->MEDIUM) {
        ceilingFan->medium();
    } else if(prevSpeed == ceilingFan->LOW) {
        ceilingFan->low();
    } else if(prevSpeed == ceilingFan->OFF) {
        ceilingFan->off();
    }
}

CeilingFanMediumCommand 类:

#ifndef CEILINGFANMEDIUMCOMMAND_H
#define CEILINGFANMEDIUMCOMMAND_H

#include "command.h"
#include "ceilingfan.h"

class CeilingFanMediumCommand : public Command
{
public:
    CeilingFanMediumCommand(CeilingFan *ceilingFan);
    void execute() override;
    void undo() override;

private:
    CeilingFan *ceilingFan;
    int prevSpeed;
};

#endif // CEILINGFANMEDIUMCOMMAND_H

#include "ceilingfanmediumcommand.h"

CeilingFanMediumCommand::CeilingFanMediumCommand(CeilingFan *ceilingFan)
{
    this->ceilingFan = ceilingFan;
}

void CeilingFanMediumCommand::execute()
{
    prevSpeed = ceilingFan->getSpeed();
    ceilingFan->medium();
}

void CeilingFanMediumCommand::undo()
{
    if(prevSpeed == ceilingFan->HIGH) {
        ceilingFan->high();
    } else if(prevSpeed == ceilingFan->MEDIUM) {
        ceilingFan->medium();
    } else if(prevSpeed == ceilingFan->LOW) {
        ceilingFan->low();
    } else if(prevSpeed == ceilingFan->OFF) {
        ceilingFan->off();
    }
}

CeilingFanOffCommand类:

#ifndef CEILINGFANOFFCOMMAND_H
#define CEILINGFANOFFCOMMAND_H

#include "command.h"
#include "ceilingfan.h"

class CeilingFanOffCommand : public Command
{
public:
    CeilingFanOffCommand(CeilingFan *ceilingFan);
    void execute() override;
    void undo() override;

private:
    CeilingFan *ceilingFan;
    int prevSpeed;
};

#endif // CEILINGFANOFFCOMMAND_H

#include "ceilingfanoffcommand.h"

CeilingFanOffCommand::CeilingFanOffCommand(CeilingFan *ceilingFan)
{
    this->ceilingFan = ceilingFan;
}

void CeilingFanOffCommand::execute()
{
    prevSpeed = ceilingFan->getSpeed();
    ceilingFan->off();
}

void CeilingFanOffCommand::undo()
{
    if(prevSpeed == ceilingFan->HIGH) {
        ceilingFan->high();
    } else if(prevSpeed == ceilingFan->MEDIUM) {
        ceilingFan->medium();
    } else if(prevSpeed == ceilingFan->LOW) {
        ceilingFan->low();
    } else if(prevSpeed == ceilingFan->OFF) {
        ceilingFan->off();
    }
}

测试:

#include "mainwindow.h"
#include "simpleremotecontrol.h"
#include "light.h"
#include "lightoncommand.h"
#include "lightoffcommand.h"
#include "remoteconrol.h"
#include "stereo.h"
#include "stereoonwithcdcommand.h"
#include "stereooffcommand.h"
#include "remotecontrolwithundo.h"
#include "ceilingfan.h"
#include "ceilingfanhighcommand.h"
#include "ceilingfanmediumcommand.h"
#include "ceilingfanlowcommand.h"
#include "ceilingfanoffcommand.h"
#include "macrocommand.h"

#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
// 1.
//    SimpleRemoteControl *remote = new SimpleRemoteControl();
//    Light *light = new Light();
//    LightOnCommand *lightOn = new LightOnCommand(light);

//    remote->setCommandControl(lightOn);
//    remote->buttonWasPressed();

// 2.
//    RemoteConrol *remoteConrol = new RemoteConrol();

//    Light *livingRoomLight = new Light("Living Room");
//    Light *kitchenLight = new Light("kitchen");
//    Stereo *stereo = new Stereo("Living Room");

//    LightOnCommand *livingRoomLightOn = new LightOnCommand(livingRoomLight);
//    LightOffCommand *livingRoomLightOff = new LightOffCommand(livingRoomLight);

//    LightOnCommand *kitchenLightOn = new LightOnCommand(kitchenLight);
//    LightOffCommand *kitchenLightOff = new LightOffCommand(kitchenLight);

//    StereoOnWithCDCommand *stereoOnWithCD = new StereoOnWithCDCommand(stereo);
//    StereoOffCommand *stereoOff = new StereoOffCommand(stereo);

//    remoteConrol->setCommand(0, livingRoomLightOn, livingRoomLightOff);
//    remoteConrol->setCommand(1, kitchenLightOn, kitchenLightOff);
//    remoteConrol->setCommand(2, stereoOnWithCD, stereoOff);

//    qDebug() << remoteConrol->toString();

//    remoteConrol->onButtonWasPushed(0);
//    remoteConrol->offButtonWasPushed(0);

//    remoteConrol->onButtonWasPushed(1);
//    remoteConrol->offButtonWasPushed(1);

//    remoteConrol->onButtonWasPushed(2);
//    remoteConrol->offButtonWasPushed(2);

// 3.
//    RemoteControlWithUndo *remoteControl = new RemoteControlWithUndo();

//    Light *livingRoomLight = new Light("Living Room");

//    LightOnCommand *livingRoomLightOn = new LightOnCommand(livingRoomLight);
//    LightOffCommand *livingRoomLightOff = new LightOffCommand(livingRoomLight);

//    remoteControl->setCommand(0, livingRoomLightOn, livingRoomLightOff);

//    remoteControl->onButtonWasPushed(0);
//    remoteControl->offButtonWasPushed(0);
//    qDebug() << remoteControl->toString();

//    remoteControl->undoButtonWasPushed();
//    remoteControl->offButtonWasPushed(0);
//    remoteControl->onButtonWasPushed(0);
//    qDebug() << remoteControl->toString();

//    remoteControl->undoButtonWasPushed();


// 4.
//    RemoteControlWithUndo *remoteControl = new RemoteControlWithUndo();

//    CeilingFan *ceilingFan = new CeilingFan("Living Room");

//    CeilingFanMediumCommand *ceilingFanMedium = new CeilingFanMediumCommand(ceilingFan);
//    CeilingFanHighCommand *ceilingFanHigh = new CeilingFanHighCommand(ceilingFan);
//    CeilingFanOffCommand *ceilingFanOff = new CeilingFanOffCommand(ceilingFan);

//    remoteControl->setCommand(0, ceilingFanMedium, ceilingFanOff);
//    remoteControl->setCommand(1, ceilingFanHigh, ceilingFanOff);

//    remoteControl->onButtonWasPushed(0);
//    remoteControl->offButtonWasPushed(0);
//    qDebug() << remoteControl->toString();
//    remoteControl->undoButtonWasPushed();

//    remoteControl->onButtonWasPushed(1);
//    qDebug() << remoteControl->toString();
//    remoteControl->undoButtonWasPushed();

// 5.
    RemoteControlWithUndo *remoteControl = new RemoteControlWithUndo();

    Light *livingRoomLight = new Light("Living Room");
    Stereo *stereo = new Stereo("Living Room");

    LightOnCommand *livingRoomLightOn = new LightOnCommand(livingRoomLight);
    LightOffCommand *livingRoomLightOff = new LightOffCommand(livingRoomLight);
    StereoOnWithCDCommand *stereoOnWithCD = new StereoOnWithCDCommand(stereo);
    StereoOffCommand *stereoOff = new StereoOffCommand(stereo);

    QVector<Command *> partyOn;
    partyOn.append(livingRoomLightOn);
    partyOn.append(stereoOnWithCD);

    QVector<Command *> partyOff;
    partyOff.append(livingRoomLightOff);
    partyOff.append(stereoOff);

    MacroCommand *partyOnMacro = new MacroCommand(partyOn);
    MacroCommand *partyOffMacro = new MacroCommand(partyOff);
    remoteControl->setCommand(0, partyOnMacro, partyOffMacro);

    qDebug() << remoteControl->toString();
    remoteControl->onButtonWasPushed(0);
    remoteControl->offButtonWasPushed(0);




}

MainWindow::~MainWindow()
{
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值