设计模式学习笔记(十六)——Command命令

来源:互联网 发布:中国制造业发展数据 编辑:程序博客网 时间:2024/05/22 04:45

十四、Command(命令)

情景举例:

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

代码示例:

/* 命令的公共父类:只定义了一个Execute纯虚函数。
*/
class Command {
public:
    virtual ~Command();
 
    virtual void Execute() = 0;
protected:
    Command();
};
/* 命令子类OpenCommand:构造函数需要一个Application参数
*/
class OpenCommand : public Command {
public:
    OpenCommand(Application*);
 
    virtual void Execute();
protected:
    virtual const char* AskUser();
private:
    Application* _application;
    char* _response;
};
/*
*/
OpenCommand::OpenCommand (Application* a) {
    _application = a;
}
/* 该子类的Execute操作即是使用构造函数传入的参数Application来添加一
* Document并打开该Document
*/
void OpenCommand::Execute () {
    const char* name = AskUser();
 
    if (name != 0) {
        Document* document = new Document(name);
        _application->Add(document);
        document->Open();
    }
}
/* 命令子类PasteCommand:构造函数需要一个Document参数
*/
class PasteCommand : public Command {
public:
    PasteCommand(Document*);
 
    virtual void Execute();
private:
    Document* _document;
};
 
PasteCommand::PasteCommand (Document* doc) {
    _document = doc;
}
/*该子类的Execute操作即是使用构造函数传入的Documnet来执行Paste操作
*/
void PasteCommand::Execute () {
    _document->Paste();
}
/* 对于简单的(不能取消),没有参数的命令,可以使用一个类模板
*/
template <class Receiver>
class SimpleCommand : public Command {
public:
    typedef void (Receiver::* Action)();
 
    SimpleCommand(Receiver* r, Action a) :
        _receiver(r), _action(a) { }
 
    virtual void Execute();
private:
    Action _action;
    Receiver* _receiver;
};
/*
*/
template <class Receiver>
void SimpleCommand<Receiver>::Execute () {
    (_receiver->*_action)();
}
/* 这个类模板的使用方法举例
*/
class MyClass {
public:
  void Action();
};
void dummy () {
/*
*/
MyClass* receiver = new MyClass;
// ...
Command* aCommand =
    new SimpleCommand<MyClass>(receiver, &MyClass::Action);
// ...
aCommand->Execute();
/*
*/
}
/* 这是一个宏命令,可以连续执行多个命令。这里子命令没有参数的原因是已
* 经假定这些子命令定义了它们各自的接受者
*/
class MacroCommand : public Command {
public:
    MacroCommand();
    virtual ~MacroCommand();
 
    virtual void Add(Command*);
    virtual void Remove(Command*);
 
    virtual void Execute();
private:
    List<Command*>* _cmds;
};
/*
*/
void MacroCommand::Execute () {
    ListIterator<Command*> i(_cmds);
 
    for (i.First(); !i.IsDone(); i.Next()) {
        Command* c = i.CurrentItem();
        c->Execute();
    }
}
/*
*/
void MacroCommand::Add (Command* c) {
    _cmds->Append(c);
}
 
void MacroCommand::Remove (Command* c) {
    _cmds->Remove(c);
}

 

个人理解:

命令模式,简单来说,就是将命令看做对象。这些对象拥有共同的父类(例子中的Command类),而子类则各自定制各种命名格式,比如例子中的打开、粘贴等。而这些子类需要各自不同的参数来使各自的命令能执行下去(也可以不要,例子中的类模板),这些参数在构造函数中传入并存在私有变量中。

由于命令子类的可以随心所欲的定制,命令模式的复杂程度应该远远大于例子所展示的那样。