您的位置:首页 > 编程语言 > Qt开发

设计模式 组合模式

2011-09-12 10:39 190 查看
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 _^_ ===
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息