コード設計モードの組合せモード(Composite)
5825 ワード
機能:
コンビネーション・モードは、部分的・全体的なモードとも呼ばれ、ツリー型構造の問題では、単純な要素と複雑な要素の概念が曖昧になり、クライアント・プログラムは単純な要素を処理するように複雑な要素を処理することができ、クライアント・プログラムを複雑な要素の内部構造とデカップリングすることができます.オブジェクトをツリー構造に結合して、「部分-全体」の階層を表します.Compositeモードでは、単一のオブジェクトと組合せオブジェクトの使用に一貫性があります.
メリット:
基本オブジェクトと組合せオブジェクトを含むクラス階層を定義組合せモードでは、基本オブジェクトをより複雑な組合せオブジェクトに組み合わせることができ、組合せオブジェクトをより複雑な組合せオブジェクトに組み合わせることができ、絶えず再帰的に組み合わせることができ、統一された組合せオブジェクトのクラス階層を構成する
組み合わせオブジェクトとリーフオブジェクトを統一
コンビネーションモードでは、リーフオブジェクトを特殊なコンビネーションオブジェクトとして扱い、統合された親クラスを定義し、コンビネーションオブジェクトとリーフオブジェクトの動作を統一できます.
クライアント・コールのシンプル化
コンビネーションモードは、コンビネーションオブジェクトとリーフオブジェクトを統一することで、クライアントがそれらを使用するときに、それらを区別する必要がなくなり、クライアントが使用するオブジェクトがどのようなタイプなのか気にしないため、クライアントの使用を大幅に簡素化します.
拡張性の向上
クライアントはComponentに対して統一的に動作するため、新しい定義のCompositeまたはLeafサブクラスは既存の構造と容易に動作し、クライアントは新しいコンポーネントクラスを追加するために変更する必要はありません.
欠点:
コンビネーション内のコンポーネントタイプを制限することが難しく、新しいコンポーネントを追加しやすくすることも、コンビネーション内のコンポーネントタイプを制限することが難しいなどの問題をもたらします.これは、コンポーネントタイプを検出する必要がある場合に、コンパイル期間のタイプ制約に依存して完了することができず、実行中に動的に検出する必要があります.
適用性は、次の場合に適用されます.1.オブジェクトの部分-全体の階層を表示したい2.グループ化されたオブジェクトと単一のオブジェクトの違いを無視したい場合、ユーザーはグループ化された構造内のすべてのオブジェクトを統一的に使用します.
例:
機械メーカーの下には、各独立した機械(concreteMachine)を管理して正常な運転を行うための統一管理部品(composite)があります.管理部品では、自分が管理している機器の運転を正確に管理すればよいだけで、具体的にどの機器が動いているのか気にしなくてもよい.
クラス図:
実装コード:
machine.h
machine.cpp
machinecomposite.h
machinecomposite.cpp
abstractmachine.h
abstractmachine.cpp
concretemachine.h
concretemachine.cpp
concretemachine2.h
concretemachine2.cpp
デモコード:
コンビネーション・モードは、部分的・全体的なモードとも呼ばれ、ツリー型構造の問題では、単純な要素と複雑な要素の概念が曖昧になり、クライアント・プログラムは単純な要素を処理するように複雑な要素を処理することができ、クライアント・プログラムを複雑な要素の内部構造とデカップリングすることができます.オブジェクトをツリー構造に結合して、「部分-全体」の階層を表します.Compositeモードでは、単一のオブジェクトと組合せオブジェクトの使用に一貫性があります.
メリット:
基本オブジェクトと組合せオブジェクトを含むクラス階層を定義組合せモードでは、基本オブジェクトをより複雑な組合せオブジェクトに組み合わせることができ、組合せオブジェクトをより複雑な組合せオブジェクトに組み合わせることができ、絶えず再帰的に組み合わせることができ、統一された組合せオブジェクトのクラス階層を構成する
組み合わせオブジェクトとリーフオブジェクトを統一
コンビネーションモードでは、リーフオブジェクトを特殊なコンビネーションオブジェクトとして扱い、統合された親クラスを定義し、コンビネーションオブジェクトとリーフオブジェクトの動作を統一できます.
クライアント・コールのシンプル化
コンビネーションモードは、コンビネーションオブジェクトとリーフオブジェクトを統一することで、クライアントがそれらを使用するときに、それらを区別する必要がなくなり、クライアントが使用するオブジェクトがどのようなタイプなのか気にしないため、クライアントの使用を大幅に簡素化します.
拡張性の向上
クライアントはComponentに対して統一的に動作するため、新しい定義のCompositeまたはLeafサブクラスは既存の構造と容易に動作し、クライアントは新しいコンポーネントクラスを追加するために変更する必要はありません.
欠点:
コンビネーション内のコンポーネントタイプを制限することが難しく、新しいコンポーネントを追加しやすくすることも、コンビネーション内のコンポーネントタイプを制限することが難しいなどの問題をもたらします.これは、コンポーネントタイプを検出する必要がある場合に、コンパイル期間のタイプ制約に依存して完了することができず、実行中に動的に検出する必要があります.
適用性は、次の場合に適用されます.1.オブジェクトの部分-全体の階層を表示したい2.グループ化されたオブジェクトと単一のオブジェクトの違いを無視したい場合、ユーザーはグループ化された構造内のすべてのオブジェクトを統一的に使用します.
例:
機械メーカーの下には、各独立した機械(concreteMachine)を管理して正常な運転を行うための統一管理部品(composite)があります.管理部品では、自分が管理している機器の運転を正確に管理すればよいだけで、具体的にどの機器が動いているのか気にしなくてもよい.
クラス図:
実装コード:
machine.h
#ifndef MACHINE_H
#define MACHINE_H
class Machine
{
public:
Machine(void);
~Machine(void);
virtual void start(){};
virtual void run(){};
virtual void stop(){};
protected:
virtual bool addMachine(Machine* mac);
virtual bool removeMachine(Machine* mac);
virtual Machine* getMachine(int index);
};
#endif
machine.cpp
#include "StdAfx.h"
#include "machine.h"
Machine::Machine(void)
{
}
Machine::~Machine(void)
{
}
bool Machine::addMachine( Machine* mac )
{
return false;
}
bool Machine::removeMachine( Machine* mac )
{
return false;
}
Machine* Machine::getMachine( int index )
{
return NULL;
}
machinecomposite.h
#ifndef CMACHINECOMPOSITE_H
#define CMACHINECOMPOSITE_H
#include "machine.h"
#include
class CMachineComposite : public Machine
{
public:
CMachineComposite(void);
~CMachineComposite(void);
bool addMachine(Machine* mac);
bool removeMachine(Machine* mac);
Machine* getMachine(int index);
private:
std::vector m_machineList;
};
#endif
machinecomposite.cpp
#include "StdAfx.h"
#include "machineComposite.h"
#include
CMachineComposite::CMachineComposite(void)
{
}
CMachineComposite::~CMachineComposite(void)
{
}
bool CMachineComposite::addMachine( Machine* mac )
{
m_machineList.push_back(mac);
return true;
}
bool CMachineComposite::removeMachine( Machine* mac )
{
std::vector::iterator it;
it = find(m_machineList.begin(),m_machineList.end(),mac);
if (m_machineList.end() != it)
{
m_machineList.erase(it);
return true;
}
return false;
}
Machine* CMachineComposite::getMachine( int index )
{
return m_machineList[index];
}
abstractmachine.h
#ifndef CABSTRACTMACHINE_H
#define CABSTRACTMACHINE_H
#include "machine.h"
class CAbstractMachine : public Machine
{
public:
CAbstractMachine(void);
~CAbstractMachine(void);
void start();
void run();
void stop();
};
#endif
abstractmachine.cpp
#include "StdAfx.h"
#include "abstractMachine.h"
CAbstractMachine::CAbstractMachine(void)
{
}
CAbstractMachine::~CAbstractMachine(void)
{
}
void CAbstractMachine::start()
{
}
void CAbstractMachine::run()
{
}
void CAbstractMachine::stop()
{
}
concretemachine.h
#ifndef CONCRETEMACHINE_H
#define CONCRETEMACHINE_H
#include "abstractMachine.h"
#include
class ConcreteMachine : public CAbstractMachine
{
public:
ConcreteMachine(void);
~ConcreteMachine(void);
void start();
void run();
void stop();
};
#endif
concretemachine.cpp
#include "StdAfx.h"
#include "concreteMachine.h"
ConcreteMachine::ConcreteMachine(void)
{
}
ConcreteMachine::~ConcreteMachine(void)
{
}
void ConcreteMachine::start()
{
std::cout<
concretemachine2.h
#ifndef CONCRETEMACHINE_HH
#define CONCRETEMACHINE_HH
#include "abstractMachine.h"
#include
class ConcreteMachine2 : public CAbstractMachine
{
public:
ConcreteMachine2(void);
~ConcreteMachine2(void);
void start();
void run();
void stop();
};
#endif
concretemachine2.cpp
#include "StdAfx.h"
#include "concreteMachine2.h"
ConcreteMachine2::ConcreteMachine2(void)
{
}
ConcreteMachine2::~ConcreteMachine2(void)
{
}
void ConcreteMachine2::start()
{
std::cout<
デモコード:
// Composite.cpp : 。
//
#include "stdafx.h"
#include "stdlib.h"
#include "machineComposite.h"
#include "concreteMachine.h"
#include "concreteMachine2.h"
int _tmain(int argc, _TCHAR* argv[])
{
ConcreteMachine* mc1 = new ConcreteMachine();
ConcreteMachine2* mc2 = new ConcreteMachine2();
CMachineComposite* mc = new CMachineComposite();
mc->addMachine(mc1);
mc->addMachine(mc2);
mc->getMachine(1)->start();
mc->getMachine(1)->run();
mc->getMachine(1)->stop();
mc->getMachine(0)->start();
mc->getMachine(0)->run();
mc->getMachine(0)->stop();
mc->removeMachine(mc1);
delete mc1;
delete mc2;
delete mc;
system("pause");
return 0;
}