现在的位置: 首页 > 综合 > 正文

设计模式中结构型模式(三)组合模式(Composite)

2017年12月07日 ⁄ 综合 ⁄ 共 9136字 ⁄ 字号 评论关闭

意图:将对象组合成树形结构以表示“部分-整体”的层次结构。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(板卡)

 图形从上往下读,机箱下面是主板,主板下包含总线和磁盘,总线下包含板卡

 代码部分详细描述了计算机组成的树形结构的表示方法,并利用这种树形结构计算各部件的价钱总数:

 

// Composite.h: interface for the CComposite class.
//
//////////////////////////////////////////////////////////////////////

#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;
}


抱歉!评论已关闭.