《C++新经典设计模式》之第9章 命令模式
命令模式.cpp
#include #include #include using namespace std;namespace ns1{class Cook {public:void cook_fish() { cout << "fish" << endl; } void cook_meat() { cout << "meat" << endl; } };class Command {protected:shared_ptr<Cook> m_pcook;public:Command(const shared_ptr<Cook> &pcook) : m_pcook(pcook) {}virtual ~Command() {}virtual void Execute() = 0;};class CommandFish : public Command {public:CommandFish(const shared_ptr<Cook> &pcook) : Command(pcook) {}void Execute() override { m_pcook->cook_fish(); }};class CommandMeat : public Command {public:CommandMeat(const shared_ptr<Cook> &pcook) : Command(pcook) {}void Execute() override { m_pcook->cook_meat(); }};class Waiter0 {shared_ptr<Command> m_pcommand; public:void SetCommand(const shared_ptr<Command> &pcommand) { m_pcommand = pcommand; } void Notify() { m_pcommand->Execute(); }};class Waiter{private:list<shared_ptr<Command>> m_commlist; public:void AddCommand(const shared_ptr<Command> &pcommand){m_commlist.push_back(pcommand);}void DelCommand(const shared_ptr<Command> &pcommand) {m_commlist.remove(pcommand);}void Notify() {for (auto iter = m_commlist.cbegin(); iter != m_commlist.cend(); ++iter) (*iter)->Execute();}};}namespace ns2{class Cook {public:void cook_fish() { cout << "fish" << endl; } void cook_meat() { cout << "meat" << endl; } };class Command {protected:shared_ptr<Cook> m_pcook;public:Command(const shared_ptr<Cook> &pcook) : m_pcook(pcook) {}virtual ~Command() {}virtual void Execute() = 0;};class CommandFish : public Command {public:CommandFish(const shared_ptr<Cook> &pcook) : Command(pcook) {}void Execute() override { m_pcook->cook_fish(); }};class CommandMeat : public Command {public:CommandMeat(const shared_ptr<Cook> &pcook) : Command(pcook) {}void Execute() override { m_pcook->cook_meat(); }};class Traineewaiter {shared_ptr<Command> m_pcommand; public:Traineewaiter(const shared_ptr<Command> &pcommand) : m_pcommand(pcommand) {}void Notify() {if (m_pcommand != nullptr)m_pcommand->Execute();}};}namespace ns3{class Cook {public:void cook_fish() { cout << "fish" << endl; } void cook_meat() { cout << "meat" << endl; } };class Command {protected:shared_ptr<Cook> m_pcook;public:Command(const shared_ptr<Cook> &pcook = nullptr) : m_pcook(pcook) {}virtual ~Command() {}virtual void Execute() = 0;};class CommandFish : public Command {public:CommandFish(const shared_ptr<Cook> &pcook = nullptr) : Command(pcook) {}void Execute() override{if (m_pcook != nullptr)m_pcook->cook_fish();}};class CommandMeat : public Command {public:CommandMeat(const shared_ptr<Cook> &pcook = nullptr) : Command(pcook) {}void Execute() override{if (m_pcook != nullptr)m_pcook->cook_meat();}};class CommandMacro : public Command {list<shared_ptr<Command>> m_commlist;public:void AddCommand(const shared_ptr<Command> &pcommand){m_commlist.push_back(pcommand);}virtual void Execute(){for (auto iter = m_commlist.cbegin(); iter != m_commlist.cend(); ++iter)(*iter)->Execute();}};class Traineewaiter {shared_ptr<Command> m_pcommand; public:Traineewaiter(const shared_ptr<Command> &pcommand = nullptr) : m_pcommand(pcommand) {}void Notify() {if (m_pcommand != nullptr)m_pcommand->Execute();}};}namespace ns4{class TC{public:void operator()(int tv){cout << "TC::operator(int tv), tv=" << tv << endl;}public:int operator()(int tv1, int tv2){cout << "TC::operator(int tv1, int tv2), tv1=" << tv1 << ", tv2=" << tv2 << endl;return tv1 + tv2;}};template <class T>void functmptest(T callobj) {callobj(100);}}int main(){#if 0using namespace ns1;shared_ptr<Cook> pcook(new Cook());pcook->cook_fish();pcook->cook_meat();#endif#if 0using namespace ns1;shared_ptr<Cook> cook(new Cook());shared_ptr<Command> pcmd1(new CommandFish(cook));pcmd1->Execute(); shared_ptr<Command> pcmd2(new CommandMeat(cook));pcmd2->Execute(); #endif#if 0using namespace ns1;shared_ptr<Cook> cook(new Cook());shared_ptr<Command> pcmd1(new CommandFish(cook));shared_ptr<Command> pcmd2(new CommandMeat(cook));shared_ptr<Waiter0> pwaiter(new Waiter0());pwaiter->SetCommand(pcmd1);pwaiter->Notify(); pwaiter->SetCommand(pcmd2);pwaiter->Notify(); #endif#if 0using namespace ns1;shared_ptr<Cook> cook(new Cook());shared_ptr<Command> pcmd1(new CommandFish(cook));shared_ptr<Command> pcmd2(new CommandMeat(cook));shared_ptr<Waiter> pwaiter(new Waiter());pwaiter->AddCommand(pcmd1);pwaiter->AddCommand(pcmd2);pwaiter->Notify();#endif#if 0using namespace ns2;shared_ptr<Cook> cook(new Cook());shared_ptr<Command> pcmd1(new CommandFish(cook));shared_ptr<Command> pcmd2(new CommandMeat(cook));shared_ptr<Traineewaiter> pwaitersx1(new Traineewaiter(pcmd1));pwaitersx1->Notify(); shared_ptr<Traineewaiter> pwaitersx2(new Traineewaiter(pcmd2));pwaitersx2->Notify(); #endif#if 0using namespace ns3;shared_ptr<Cook> cook(new Cook());shared_ptr<Command> pcmd1(new CommandFish(cook));shared_ptr<Command> pcmd2(new CommandMeat(cook));shared_ptr<CommandMacro> pcmd(new CommandMacro());shared_ptr<Traineewaiter> pwaiter(new Traineewaiter(pcmd));pcmd->AddCommand(pcmd1);pcmd->AddCommand(pcmd2);pwaiter->Notify();#endif#if 1using namespace ns4;TC tc;tc(20); cout << tc(30, 50) << endl;functmptest(tc);#endifcout << "Over!\n";return 0;}