命令模式.cpp
#include <iostream>
#include <list>
#include <memory>
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 0
using namespace ns1;
shared_ptr<Cook> pcook(new Cook());
pcook->cook_fish();
pcook->cook_meat();
#endif
#if 0
using 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 0
using 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 0
using 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 0
using 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 0
using 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 1
using namespace ns4;
TC tc;
tc(20);
cout << tc(30, 50) << endl;
functmptest(tc);
#endif
cout << "Over!\n";
return 0;
}