複合モード
要素のリストに親クラス(ポインタ)を維持するために、複合クラスは、それが実際に代理親クラスであるが、複合クラスを使用することができる任意の場所に親クラスまたはサブクラスの他の親を使用することができます。
C ++の実装
/*这个Composite模式的实现是在实现Command模式的代码的基础上更改的,两个可以比较着看*/
#include<iostream>
#include<vector>
using namespace std;
class Command {
public:
virtual void doit() {
cout << "command\n";
}
};
//在CompositeCommand类中维护一个Command*的列表
//让CompositeCommand继承Command类,这样凡是可以用Command的地方都可以用CompositeCommand
//这样就实现了执行一个命令的代码和执行若干个命令的代码是一样的
class CompositeCommand : public Command {
public:
virtual void doit() {
for (auto i = commands.begin(); i != commands.end(); ++i) {
Command* command = *i;//*i -> doit(): error, 'cause *i isn't taken as a pointer
command->doit();
}
}
void add(Command* command) {//为了简单,这里只写了添加命令的代码,没写删除命令的
commands.push_back(command);
}
private:
vector<Command*> commands;
};
//下面是会绑定到Sensor上的三个命令
class TurnonCommand : public Command {
public:
virtual void doit() {
cout << "turn on\n";
}
};
class TurnoffCommand : public Command {
public:
virtual void doit() {
cout << "turn off\n";
}
};
class PrintCommand : public Command {
public:
virtual void doit() {
cout << "print\n";
}
};
//和Command模式比较会发现,Sensor类的代码是完全一样的
class Sensor {
public:
Sensor(Command* c) : command(c) {}
void sense() {
if (condition)
command->doit();
}
private:
bool condition = true;
Command* command;
};
int main() {
TurnonCommand turnOn = TurnonCommand();
PrintCommand print = PrintCommand();
TurnoffCommand turnOff = TurnoffCommand();
CompositeCommand commands = CompositeCommand();
commands.add(&turnOn);
commands.add(&print);
commands.add(&turnOff);
Sensor s = Sensor(&commands);//需要更改这个Sensor执行的命令时,
//只需要再初始化一个Command的derived class,
//然后添加到commands里就可以了,
//不需要更改Sensor的代码
s.sense();
return 0;
}
コンポジットモードを備えています
変換関係「一対一」の(このようなセンサやコマンドの複数のような)関係「多くの1つは」(センサとCompositeCommandは、CompositeCommandクラスは、コマンドのよう*の要素のリストを維持する)コードは、そのようなOCPに沿ったもので、保守が容易。
しかし、このモデルにも限界があります:複合クラスは、同じように、リストのすべての要素を扱う必要があります。使用コンポジットモード「Aに適し例えば、我々は今、オブジェクトのリストを保持し、リストで、今日の従業員のスタッフの賃金を検索し、すべての従業員を同じように扱うことはありません(一部の賃金および一部は送信しない)、そのためではありません一から一「を」マルチ。」