第35章
小a:“组合模式比较简单,也很容易学习,当你面对一个树形结构的时候,脑筋就该多转一圈:是否可以在该结构中使用组合模式?”
大b:“我跟你讲一种简单的方法:定义一个公用的接口,让组合对象和单个对象都去实现该接口。因此,如果面对单个对象,则调用单个对象的方法;如果面对组合对象,递归遍历之,依次调用每个对象的方法;单个对象:相当于树形结构中的叶节点,它不包含任何子对象。”
小a:“如何去实现组合模式呢?”
大b:“组合对象相当于树形结构中的枝节点,它可以包含更小的枝对象,也可以包含叶对象。下面的代码是以抽象类定义,一般尽量用接口interface。”
publicabstractclassequipment
{
privatestringname;
//实价
publicabstractdoublenetprice();
//折扣价格
publicabstractdoublediscountprice();
//增加部件方法
publicbooleanadd(equipmentequipment){returnfalse;}
//删除部件方法
publicbooleanremove(equipmentequipment){returnfalse;}
//注重这里,这里就提供一种用于访问组合体类的部件方法。
publiciteratoriter(){returnnull;}
publicequipment(finalstringname){this.name=name;}
}
大b:“抽象类equipment就是component定义,代表着组合体类的对象们,equipment中定义几个共同的方法。”
publicclassdiskextendsequipment
{
publicdisk(stringname){super(name);}
//定义disk实价为。
publicdoublenetprice(){return1.;}
//定义了disk折扣价格是0.5对折。
publicdoublediscountprice(){return.5;}
}
小a:“什么是disk?”
大b:“disk是组合体内的一个对象,或称一个部件,这个部件是个单独元素(primitive)。还有一种可能是,一个部件也是一个组合体,就是说这个部件下面还有‘儿子’,这是树形结构中通常的情况,应该比较轻易理解。”
现在我们先要定义这个组合体:
abstractclasscompositeequipmentextendsequipment
{
privateinti=0;
//定义一个vector用来存放‘儿子’
privatelsitequipment=newarraylist();
publiccompositeequipment(stringname){super(name);}
publicbooleanadd(equipmentequipment){
this.equipment.add(equipment);
returntrue;
}
publicdoublenetprice()
{
doublenetprice=0.;
iteratoriter=equipment.iterator();
for(iter.hasnext())
netprice+=((equipment)iter.next()).netprice();
returnnetprice;
}
publicdoublediscountprice()
{
doublediscountprice=0.;
iteratoriter=equipment.iterator();
for(iter.hasnext())
discountprice+=((equipment)iter.next()).discountprice();
returndiscountprice;
}
//注重这里,这里就提供用于访问自己组合体内的部件方法。
//上面disk之所以没有,是因为disk是个单独(primitive)的元素。
publiciteratoriter()
{
returnequipment.iterator()
{
//重载iterator方法
publicbooleanhasnext(){returni