特性:
组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
意图
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite模式使得用户对单个对象和组合对象的使用具有一致性。
优点:
定义了包含基本对象和组合对象的类层次结构
在组合模式中,基本对象可以被组合成更复杂的组合对象,而组合对象又可以组合成更复杂的组合对象,可以不断地递归组合下去,从而构成一个统一的组合对象的类层次结构
统一了组合对象和叶子对象
在组合模式中,可以把叶子对象当作特殊的组合对象看待,为它们定义统一的父类,从而把组合对象和叶子对象的行为统一起来
简化了客户端调用
组合模式通过统一组合对象和叶子对象,使得客户端在使用它们的时候,就不需要再去区分它们,客户不关心使用的到底是什么类型的对象,这就大大简化了客户端的使用
更容易扩展
由于客户端是统一的面对Component来操作,因此,新定义的Composite或Leaf子类能够很容易的与已有的结构一起工作,而客户端不需要为增添了新的组件类而改变
缺点:
很难限制组合中的组件类型
容易增加新的组件也会带来一些问题,比如很难限制组合中的组件类型。这在需要检测组件类型的时候,使得我们不能依靠编译期的类型约束来完成,必须在运行期间动态检测。
适用性
以下情况下适用Composite模式:
1.你想表示对象的部分-整体层次结构
2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
例子:
一个机器生产厂商,下面有一个统一管理的部件(composite),用来管理每个独立的机器(concreteMachine),以进行正常运转。管理部件中只需要正确的管理自身所管理的机器运行即可,而不用关心具体是什么机器在运转。
类图:
实现代码:
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<<"Machine 1 have start."<
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<<"Machine 2 have start."<
演示代码:
// 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;
}