惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Latest
Security Latest
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
N
Netflix TechBlog - Medium
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
T
Tor Project blog
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
MongoDB | Blog
MongoDB | Blog
Simon Willison's Weblog
Simon Willison's Weblog
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
小众软件
小众软件
G
GRAHAM CLULEY
P
Privacy International News Feed
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
人人都是产品经理
人人都是产品经理
S
Schneier on Security
Scott Helme
Scott Helme
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
T
The Exploit Database - CXSecurity.com
Recent Announcements
Recent Announcements
E
Exploit-DB.com RSS Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
U
Unit 42
The Register - Security
The Register - Security
S
Securelist
Martin Fowler
Martin Fowler
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
Cisco Talos Blog
Cisco Talos Blog

博客园 - 鬼谷子com

2026年国内主流AI Coding Plan套餐全对比|开发者避坑指南 图解 | 你管这破玩意儿叫TCP?(转载) C++ static_cast、dynamic_cast、const_cast和reinterpret_cast(四种类型转换运算符) Qt内部的d指针和q指针手把手教你实现 C++中虚函数、虚继承内存模型 c++11新特性实战(二):智能指针 windows下使用mingw和msvc静态编译Qt5.15.xx Qt moc元对象编译器的原理和场景(反射) c++结构体内存对齐 c++11新特性实战 (一):多线程操作 抽象工厂模式(c++实现) 迭代器模式(c++实现) 中介者模式(c++实现) 享元模式(c++实现) 代理模式(c++实现) 状态模式(c++实现) - 鬼谷子com 建造者模式(c++实现) 职责链模式(c++实现) 模板方法模式(c++实现)
命令模式(c++实现)
鬼谷子com · 2020-07-15 · via 博客园 - 鬼谷子com

命令模式

模式定义

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

模式动机

  • 敏捷开发的原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能时,把原来的代码重构为命令模式才有意义。

UML类图

源码实现

  • command.h
#include "chef.h"

class Command
{
public:
    Command(Chef* chef);
    virtual ~Command();
    virtual void ExcuteCmd();

protected:
    Chef*   m_Chef;
};
  • chef.h
class Chef
{
public:
    Chef();
    void KungPaoChicken();
    void FishFlavoredShreddedPork();
    void BigPlateChicken();
};
  • chef.cpp
#include "chef.h"
#include <iostream>
Chef::Chef()
{

}

void Chef::KungPaoChicken()
{
    std::cout << "宫保鸡丁" << std::endl;
}

void Chef::FishFlavoredShreddedPork()
{
    std::cout << "鱼香肉丝" << std::endl;
}

void Chef::BigPlateChicken()
{
    std::cout << "大盘鸡" << std::endl;
}

  • kungpaochickencmd.h
#include "command.h"
#include "chef.h"

class KungPaoChickenCmd : public Command
{
public:
    KungPaoChickenCmd(Chef* chef);
    void ExcuteCmd() override;
};
  • kungpaochickencmd.cpp
#include "kungpaochickencmd.h"

KungPaoChickenCmd::KungPaoChickenCmd(Chef* chef)
    :Command(chef)
{

}

void KungPaoChickenCmd::ExcuteCmd()
{
    m_Chef->KungPaoChicken();
}
  • waiter.h
#include <list>
#include <command.h>

class Waiter
{
public:
    Waiter();
    void AddCmd(Command* cmd);
    void DelCmd(Command* cmd);
    void Nodify();
private:
    std::list<Command*>     m_CmdList;
};
  • waiter.cpp
#include "waiter.h"

Waiter::Waiter()
{

}

void Waiter::AddCmd(Command *cmd)
{
    m_CmdList.push_back(cmd);
}

void Waiter::DelCmd(Command *cmd)
{
    m_CmdList.remove(cmd);
}

void Waiter::Nodify()
{
    for(auto cmd : m_CmdList)
    {
        if(cmd)
            cmd->ExcuteCmd();
    }
}
  • main.cpp
#include <iostream>
#include "fishflavoredshreddedporkcmd.h"
#include "kungpaochickencmd.h"
#include "bigplatechickencmd.h"
#include "waiter.h"
#include <memory>
int main()
{
    std::shared_ptr<Chef> chef = std::make_shared<Chef>();
    Waiter waiter;

    std::shared_ptr<FishFlavoredShreddedPorkCmd> ffspc = std::make_shared<FishFlavoredShreddedPorkCmd>(chef.get());
    std::shared_ptr<KungPaoChickenCmd> kpcc = std::make_shared<KungPaoChickenCmd>(chef);
    std::shared_ptr<BigPlateChickenCmd> bpcc = std::make_shared<BigPlateChickenCmd>(chef);

    waiter.AddCmd(ffspc.get());
    waiter.AddCmd(kpcc.get());
    waiter.AddCmd(bpcc.get());
    //        waiter.DelCmd(kpcc.get);

    waiter.Nodify();
    return 0;
}

  • 运行结果

鱼香肉丝

宫保鸡丁

大盘鸡

优点

命令模式的优点

  • 它能较容易的设计一个命令队列;
  • 在需要的情况下,可以较容易的将命令计入日志;
  • 允许接收请求的一方决定是否要否决请求;
  • 可以容易的实现对请求的撤销和重做;
  • 由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易;
  • 把请求一个操作的对象与知道怎么执行一个操作的对象分隔开;

缺点

模式的缺点