C++设计模式学习------组合模式

 每次写博客都要出点状况,好容易写完了,电脑死机了。无奈,白费功夫。好吧,我吸取教训,先写在OneNote里面。

        由于《Head first设计模式》和《大话设计模式》这两本比较通俗的书一个是Java,一个是C#,虽说原理都是一样的,但是在某些数据结构上面C++还是跟这两者有区别的,并且C++关于对象用指针还是引用的问题困扰我很久,于是边学习的同时,我用C++实现这些设计模式,也算是同时熟悉C++了。

        今天学习的模式是组合模式,组合模式用于将对象组合成树形结构以表示“部分--整体”的层次结构。使得用户对单个对象和组合对象的使用具有一致性。

        什么意思呢,比如公司的组成就是一个典型的树形结构,举个例子如下图:

C++设计模式学习------组合模式_第1张图片

         这里每个人所扮演的角色不同,行驶的职能也不同,在写程序的时候,要区分他们需要在客户端有很多的判断语句。但是通过组合模式,就可以将他们抽象出来,不论是总经理还是职员,都是人,都具有执行任务的能力,因此可以统一抽象。并且为了能够在派生出的对象上还可以延伸出结点,因此将对象做成容器。这么说有点抽象,先看UML图:

        这里Component类定义了一个结点的抽象,Operation()是具体执行的方法,Add()Remove()GetChild()都是为了将这个抽象做成容器而创造的方法。Leaf类为叶子结点,也就是说它不能再派生出子结点,因此它只用实现Operation()函数就行了。而Composite类则是结点类,它能够再派生出子节点,因此它要将Component类的函数全都实现。

        现在来看代码吧:(声明:这些代码并非笔者原创,借鉴的成分占多数,我只是修改了其中一些部分)

        首先是Component.h,它是一个纯虚函数,没有.cpp文件,并且不能用来实例化对象

#pragmaonce
classComponent
{
public:
    virtual void Operation() = 0;//纯虚函数,只提供接口,没有默认实现
   
    virtual void Add( Component *com );//增加一个Component对象
    virtual void Remove( Component *com );//移除一个Component对象
    virtual Component* GetChild( int index );//得到指定Component对象的指针
    virtual ~Component();
   
protected:
    Component();
   
};

Leaf.h

#pragmaonce
#include"Component.h"
 
//Leaf是叶子结点,也就是不含有子组件的结点类,所以不用实现Add、Remove、GetChild等方法
classLeaf: public Component
{
public:
    Leaf( void );
    ~Leaf( void );
   
    virtual void Operation();
};

Leaf.cpp

#include"Leaf.h"
#include<iostream>
 
usingnamespace std;
 
Leaf::Leaf(void )
{
}
 
Leaf::~Leaf(void )
{
}
 
voidLeaf::Operation()
{
    cout << "Leaf::Operation"<< endl;
}

Composite.h 这个类必须实现Component的所有函数。

#pragmaonce
#include"Component.h"
#include<vector>
 
usingnamespace std;
 
// 含有子组件的类
classComposite: public Component
{
public:
    Composite( void );
    ~Composite( void );
   
    void Operation();
    void Add( Component *com );
    void Remove( Component *com );
    Component* GetChild( int index );
   
private:
    vector<Component *> m_ComVec;
};

 

Composite.cpp

#include"Composite.h"
#include<iostream>
 
usingnamespace std;
 
Composite::Composite(void )
{
}
 
 
Composite::~Composite(void )
{
}
 
voidComposite::Operation()
{
    cout <<"Composite::Operation" << endl;
    vector<Component*>::iterator iter =this->m_ComVec.begin();
    for ( ; iter != m_ComVec.end(); iter++ )
    {
        ( *iter )->Operation();
    }
}
 
voidComposite::Add( Component *com )
{
    this->m_ComVec.push_back( com );
}
 
voidComposite::Remove( Component *com )
{
    vector<Component*>::iterator iter =this->m_ComVec.begin();
    for ( ; iter != this->m_ComVec.end();iter++ )
    {
        if ( *iter == com )
        {
            this->m_ComVec.erase( iter );
            iter = m_ComVec.begin();
        }
    }
}
 
Component*Composite::GetChild( int index )
{
    if ( index < 0 || index >this->m_ComVec.size() )
    {
        return NULL;
    }
    return this->m_ComVec[index];
}

最后是 main.cpp

#include"Composite.h"
#include"Leaf.h"
 
void main()
{
    Composite *pRoot = newComposite();   // 创建一个根结点
   
    pRoot->Add( new Leaf());   // 为这个根结点添加一个叶子结点
   
    Leaf *pLeaf1 = new Leaf;  // 创建两个叶子结点
    Leaf *pLeaf2 = new Leaf;
   
    // pLeaf1->Operation();
   
    // 创建一个结点,并为它加上刚创建的两个叶子结点
    Composite *pCom = new Composite();
    pCom->Add( pLeaf1 );
    pCom->Add( pLeaf2 );
    //pCom->Operation();
   
    pRoot->Add( pCom );   // 把pCom结点添加到根结点上
   
    pRoot->Operation(); // 这里根结点执行操作会让每个结点都执行Operation()函数
 
   
   
    getchar();
}

        这里的代码也讲的很清楚了,最后我就把main里面创建的树形结构图给出来吧:

 

你可能感兴趣的:(设计模式,C++,工作,软件开发)