意图:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个
对象和组合对象的使用具有一致性。
以下情况使用Composite模式
你想表示对象的部分-整体层次结构
你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
部分示例代码:
这部分内容由于有迭代器夹在中间,感觉有一定难度,难度不在于如何实现迭代器,而在于如何补齐对应的迭代器,使其能够满足程序的测试要求。
既使这样,程序还是稍微有点与书中不同,原因是书中的代码我想破脑袋也无法实现,猜测可能是写错了。
另外,其中有一个头文件是引用BasicClass.h中的,这里面包含了关于List表的部分实现,及其相关ListIterator的实现,在对应的文件中已作了修改(链接:http://blog.csdn.net/luhouxiang/archive/2008/04/17/2301849.aspx)。需要可到相关页面更新。
到今天,组合模式终于基本了结。
以下为相关类的类图:
代码描述的是一组计算机结构。大体如下:机箱(Cabinet),主板(chassis),总线(bus),磁盘(FloppyDisk),
总线下的各种板卡(Card),程序采用树形结构将这些零件组合成一个计算机,最后给出计算整个机器的价钱的方法。
以下为整个计算机的组成结构,和类图稍有不同
Cabinet(机箱)
|
chassis(主板)
| |
bus(总线) FloppyDisk(磁盘)
|
Card(板卡)
图形从上往下读,机箱下面是主板,主板下包含总线和磁盘,总线下包含板卡
代码部分详细描述了计算机组成的树形结构的表示方法,并利用这种树形结构计算各部件的价钱总数:
//
/**///////////////////////////////////////////////////////////////////////
#if !defined(AFX_COMPOSITE_H__4A747028_E312_4DFD_8E52_F9E48CCD5929__INCLUDED_)
#define AFX_COMPOSITE_H__4A747028_E312_4DFD_8E52_F9E48CCD5929__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../BaseClass/BasicClass.h"
//##ModelId=481289160296
typedef float Currency;
//##ModelId=4812891602A3
typedef float Watt;
//##ModelId=4812891602B1
class Equipment
...{//应该是一个类似抽象类
public:
//##ModelId=4812891602B2
Equipment()...{ _name = ""; }
//##ModelId=4812891602B3
virtual ~Equipment()...{ }
//##ModelId=4812891602B5
const char* Name() const ...{ return _name; }
// virtual Watt Power(){}
//##ModelId=4812891602B7
virtual Currency NetPrice()
...{
Iterator<ListNode<Equipment*>*>* i = CreateIterator();
Currency total = 0;
total += GetCurrency();
for(i->First(); !i->IsNull(); i->Next())
...{
total += i->CurrentItem()->_data->NetPrice();// NetPrice();
}
delete i;
return total;
return 0;
}
//##ModelId=4812891602B9
virtual Currency DiscountPrice()...{ return 0; }
//##ModelId=4812891602C2
virtual void Add(Equipment*)...{}
//##ModelId=4812891602C5
virtual void Remove(Equipment*)...{}
//##ModelId=4812891602C8
virtual Iterator< ListNode<Equipment*>* >* CreateIterator()
...{
ListNode<Equipment*>* listpoint = _equipmentlist.FirstPoint();
Iterator< ListNode<Equipment*>* >* newit = new ListIterator< ListNode<Equipment*>* >(listpoint);
return newit;
}
//protected:
//##ModelId=4812891602CA
Equipment(const char* name)...{ _name = name;}
//##ModelId=4812D23D02DA
void SetCurrency(Currency cur)//设置价钱,每一个构造函数必须调用
...{
_currency = cur;
}
//##ModelId=4812D23D0318
Currency GetCurrency() const
...{
return _currency;
}
protected:
//##ModelId=4812D23D0338
List<Equipment*> _equipmentlist;
private:
//##ModelId=4812891602CC
const char* _name;
//##ModelId=4812D23D0348
Currency _currency;//价钱
};
//##ModelId=4812891602D1
class FloppyDisk: public Equipment
...{
public:
//##ModelId=4812891602D3
FloppyDisk(const char* name):Equipment(name)...{ SetCurrency(4.6); }
//##ModelId=4812891602D5
virtual ~FloppyDisk()...{}
//##ModelId=4812891602E1
virtual Watt Power()...{ printf("FloppyDisk::Power() "); return 0; }
//##ModelId=4812891602E3
virtual Currency NetPrice()
...{
printf("FloppyDisk::NetPrice() ");
return Equipment::NetPrice();
}
//##ModelId=4812891602E5
virtual Currency DiscountPrice()...{ printf("FloppyDisk::DiscountPrice() "); return 0; }
//##ModelId=4812D23D0376
virtual Iterator< ListNode<Equipment*>* >* CreateIterator()
...{
printf("FloppyDisk::CreateIterator() ");
return Equipment::CreateIterator();
}
};
//##ModelId=4812891602F0
class CompositeEquipment: public Equipment
...{
public:
//##ModelId=4812891602F2
virtual ~CompositeEquipment()...{}
//##ModelId=4812891602F4
virtual Watt Power()...{ printf("CompositeEquipment::Power() "); return 0; }
//##ModelId=4812891602F6
virtual Currency NetPrice()
...{
printf("CompositeEquipment::NetPrice() ");
return Equipment::NetPrice();
}
//##ModelId=4812891602F8
virtual Currency DiscountPrice()...{ printf("CompositeEquipment::DiscountPrice() "); return 0; }
//##ModelId=4812891602FA
virtual void Add(Equipment* peq)
...{
_equipmentlist.Append(peq);
}
//##ModelId=481289160300
virtual void Remove(Equipment* peq)
...{
_equipmentlist.Remove(peq);
}
//##ModelId=481289160303
virtual Iterator< ListNode<Equipment*>* >* CreateIterator()
...{
printf("CompositeEquipment::CreateIterator() ");
return Equipment::CreateIterator();
}
protected:
//##ModelId=481289160305
CompositeEquipment(const char* sz):Equipment(sz)...{}
private:
};
//现在我们将计算机的底盘表示为CompositeEquipment的子类Chassis
//它从CompositeEquipment继承了与子类有关的那些操作。
//##ModelId=48128916031F
class Chassis: public CompositeEquipment
...{
public:
//##ModelId=481289160321
Chassis(const char* sz):CompositeEquipment(sz)...{ SetCurrency(8); }
//##ModelId=48128916032E
virtual ~Chassis()...{}
//##ModelId=481289160330
virtual Watt Power()...{ printf("Chassis::Power() "); return 0; }
//##ModelId=481289160332
virtual Currency NetPrice()
...{
printf("Chassis::NetPrice() ");
return Equipment::NetPrice();
}
//##ModelId=4812D23D03B4
virtual Iterator< ListNode<Equipment*>* >* CreateIterator()
...{
printf("Chassis::CreateIterator() ");
return Equipment::CreateIterator();
}
//##ModelId=481289160334
virtual Currency DiscountPrice()...{ printf("Chassis::DiscountPrice() "); return 0; }
};
//我们可以用相似的方式定义其它设备容器,如Cabinet和Bus.
//##ModelId=48128916033E
class Cabinet: public CompositeEquipment
...{
public:
//##ModelId=481289160340
Cabinet(const char* sz):CompositeEquipment(sz)...{ SetCurrency(9); }
//##ModelId=481289160342
virtual ~Cabinet()...{}
//##ModelId=481289160344
virtual Watt Power()...{ printf("Cabinet::Power() "); return 0; }
//##ModelId=481289160346
virtual Currency NetPrice()
...{
printf("Cabinet::NetPrice() ");
return Equipment::NetPrice();
}
//##ModelId=4812D23D03E3
virtual Iterator< ListNode<Equipment*>* >* CreateIterator()
...{
printf("Cabinet::CreateIterator() ");
return Equipment::CreateIterator();
}
//##ModelId=481289160348
virtual Currency DiscountPrice()...{ printf("Cabinet::DiscountPrice() "); return 0; }
};
//##ModelId=48128916034E
class Bus: public CompositeEquipment
...{
public:
//##ModelId=481289160350
Bus(const char* sz):CompositeEquipment(sz)...{ SetCurrency(10); }
//##ModelId=481289160352
virtual ~Bus()...{}
//##ModelId=48128916035E
virtual Watt Power()...{ printf("Bus::Power() ");return 0; }
//##ModelId=481289160360
virtual Currency NetPrice()
...{
printf("Bus::NetPrice() ");
return Equipment::NetPrice();
}
//##ModelId=4812D23E001A
virtual Iterator< ListNode<Equipment*>* >* CreateIterator()
...{
printf("Bus::CreateIterator() ");
return Equipment::CreateIterator();
}
//##ModelId=481289160362
virtual Currency DiscountPrice()...{ printf("Bus::DiscountPrice() "); return 0; }
};
//##ModelId=4812D23E002B
class Card: public CompositeEquipment
...{
public:
//##ModelId=4812D23E003A
Card(const char* sz):CompositeEquipment(sz)...{ SetCurrency(11.1); }
//##ModelId=4812D23E003C
virtual ~Card()...{}
//##ModelId=4812D23E003E
virtual Watt Power()...{ printf("Card::Power() ");return 0; }
//##ModelId=4812D23E0040
virtual Currency NetPrice()
...{
printf("Card::NetPrice() ");
return Equipment::NetPrice();
}
//##ModelId=4812D23E0042
virtual Iterator< ListNode<Equipment*>* >* CreateIterator()
...{
printf("Card::CreateIterator() ");
return Equipment::CreateIterator();
}
//##ModelId=4812D23E004A
virtual Currency DiscountPrice()...{ printf("Card::DiscountPrice() "); return 0; }
};
#endif // !defined(AFX_COMPOSITE_H__4A747028_E312_4DFD_8E52_F9E48CCD5929__INCLUDED_)
// Composite.cpp: implementation of the CComposite class.
//
/**///////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Composite.h"
/**///////////////////////////////////////////////////////////////////////
// Construction/Destruction
/**///////////////////////////////////////////////////////////////////////
// testComposite.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Composite.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
...{
printf("Hello World! ");
Cabinet* cabinet = new Cabinet("PC Cabinet");
Chassis* chassis = new Chassis("PC Chassis");
cabinet->Add(chassis);
Bus* bus = new Bus("MCA Bus");
bus->Add( new Card("16Mbs Token Ring"));
chassis->Add(bus);
chassis->Add(new FloppyDisk("3.5in Floppy"));
cout<<"--------Cabinet:"<<cabinet->NetPrice()<<endl;
cout<<"--------Chassis:"<<chassis->NetPrice()<<endl;
cout<<"--------Bus:"<<bus->NetPrice()<<endl;
return 0;
}