设计模式 组合模式

1、menucomponent.h

#ifndef MENUCOMPONENT_H
#define MENUCOMPONENT_H

#include <string>

class MenuComponent //组合对象基类Component
{
public:
    MenuComponent(){};//构造函数
    MenuComponent(std::string strName):m_strName(strName){};//构造函数
    virtual ~MenuComponent(){};//析构函数
    virtual void Add(MenuComponent*){};//添加一个
    virtual void Remove(MenuComponent*){};//移除一个
    virtual MenuComponent* GetChild(int){return NULL;};//访问一个
    virtual void Display() = 0;//操作,Operation
protected:
    std::string m_strName;
};
#endif // MENUCOMPONENT_H

2-1、menucomposite.h

#ifndef MENUCOMPOSITE_H
#define MENUCOMPOSITE_H

#include "menucomponent.h"

#include <iostream>
#include <vector>
using namespace std;

class MenuComposite : public MenuComponent //组合对象子组件Composite(树枝)
{
public:
    MenuComposite();
    MenuComposite(std::string);
    virtual ~MenuComposite();
    //以下管理操作声明为虛函数,这样就可以被它的子类再实现,以便下一部的再组合。
    virtual void Add(MenuComponent*);
    virtual void Remove(MenuComponent*);
    virtual MenuComponent* GetChild(int);
    virtual void Display();
private:
    std::vector<MenuComponent*> m_vMenu;
};
#endif // MENUCOMPOSITE_H

2-2、menucomposite.cpp

#include "menucomposite.h"

MenuComposite::MenuComposite()
{
    cout << "this is a menucomposite"  << endl;
}

MenuComposite::MenuComposite(string strName) : MenuComponent(strName)
{
    cout << "this is a menucomposite:" << strName<< endl;
}

MenuComposite::~MenuComposite()
{

}

void MenuComposite::Add(MenuComponent* pMenu)
{
    m_vMenu.push_back(pMenu);
}

void MenuComposite::Remove(MenuComponent* pMenu)
{
    int pos =-1;
    vector<MenuComponent*>::iterator it = m_vMenu.begin();
    for (; it != m_vMenu.end(); ++it)
    {
        pos++;
        if(*it==pMenu)
        {
            break;
        }
    }
    m_vMenu.erase(m_vMenu.begin()+pos);
}

MenuComponent* MenuComposite::GetChild(int index)
{
    return m_vMenu[index];
}

void MenuComposite::Display()
{
    cout << "+" << m_strName << endl;
    vector<MenuComponent*>::iterator it = m_vMenu.begin();
    for (; it != m_vMenu.end(); ++it)
    {
        cout << "|-";
        (*it)->Display();
    }
}

3-1、menuleaf.h

#ifndef MENULEAF_H
#define MENULEAF_H

#include "menucomponent.h"

#include <iostream>
using namespace std;

class MenuLeaf : public MenuComponent//组合对象的叶子节点Leaf(树叶)
{
public:
    MenuLeaf();
    MenuLeaf(std::string);
    virtual ~MenuLeaf();

    void Display();
};
#endif // MENULEAF_H

3-2、menuleaf.cpp

#include "menuleaf.h"

MenuLeaf::MenuLeaf()
{
    cout << "this is a menuleaf"  << endl;
}

MenuLeaf::MenuLeaf(string strName) : MenuComponent(strName)
{
    cout << "this is a menuleaf:" << strName << endl;
}

MenuLeaf::~MenuLeaf()
{

}

void MenuLeaf::Display()
{
    cout << m_strName << endl;
}

4、main.cpp
/*
作者:jhluroom弹   QQ:454676244  MSN:jhlu0815@hotmail.com
开发IDE:qt creater
开发环境:QT C++
参考网站:神秘果:http://www.shenmiguo.com/

定义:
将对象组合成树形结构以表示“部分-整体”的层次结构。组合(Composite)模式使得用户对单个对象和组合对象的使用具有一致性。

理解:
1.Component是组合对象的基类,定义了类的公共方法;提供一个访问和管理子组件的方法。
  管理子组件的方法:Add-添加子组件;Remove-移除子组件;GetChild-遍历获取组建对象的指针。
  Operation是需要子组件具体定义的公共接口。
2.Leaf是组合对象的叶子节点(树叶),叶子节点没有子组件(也就没有管理子组件的方法),只有公共行为方法Operation。
3.Composite是具体的子组件类(树枝),实现基类接口,要有管理子组件的方法,它可以继续派生子组件或者叶子节点。
4.Client通过Component基类来操作组合对象。

要点:
1.组合模式提供了一种解决对象之间递归组合的解决办法。组合对象包含两种派生类:包含子组件的树枝(Composite)和
  叶子组件的树叶(Leaf)。这样组合对象就可以继续组合对象,形成复杂的组合对象应用。
2.最大化组合对象基类Component。客户是不知道具体对象调用的是Leaf还是Composite。为了达到这个目的,
  基类Component的方法就要最大化,并且提供默认实现,Leaf和Composite根据实际情况来重新实现。

应用:
多级菜单的实现可以使用组合模式,源码例子中就是这样的实现。

以上文字说明,从网上整理而来,有可能部分与其他同仁相同,请谅解,希望我们能够共同交流,谢谢!
*/

#include <QtCore/QCoreApplication>

#include "menucomponent.h"
#include "menucomposite.h"
#include "menuleaf.h"

int main(int argc, char *argv[])
{
    cout << "=== jhluroom start ========" << endl;

    //Client调用
    MenuComponent* pMenu = new MenuComposite("国内新闻");
    pMenu->Add(new MenuLeaf("时事新闻"));
    pMenu->Add(new MenuLeaf("社会新闻"));
    pMenu->Display();
    pMenu = new MenuComposite("国际新闻");
    pMenu->Add(new MenuLeaf("国际要闻"));
    pMenu->Add(new MenuLeaf("环球视野"));
    pMenu->Display();

    cout << "=== jhluroom finish _^_ ===" << endl;
}

运行结果:
=== jhluroom start ========
this is a menucomposite:国内新闻
this is a menuleaf:时事新闻
this is a menuleaf:社会新闻
+国内新闻
|-时事新闻
|-社会新闻
this is a menucomposite:国际新闻
this is a menuleaf:国际要闻
this is a menuleaf:环球视野
+国际新闻
|-国际要闻
|-环球视野

=== jhluroom finish _^_ ===


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值