zoukankan      html  css  js  c++  java
  • 设计模式之组合模式(Composite)

    组合模式为了描述分支包含关系,也就是我们说的树形关系,其对象分为枝和叶,每一枝可包含枝和叶,直到全部为叶节点。我们对枝和叶进行行为抽象,可认为枝和叶都是Component,而叶是最小的操作单元,其下不存在枝和叶,而枝作为Composite里面存有其下枝和叶的组件列表。

    作用

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

    类视图

    实现

    
    #include <iostream>
    #include <list>
    #include <string>
    using namespace std;
    class menu
    {
    public:
    	menu(string in) : name(in){}
    	~menu(){}
    	virtual void Add(menu*) = 0;
    	virtual void Remove(menu*) = 0;
    	virtual void showname() = 0;
    protected:
    	string name;
    };
    
    class Leafmenu : public menu
    {
    public:
    	Leafmenu(string in) : menu(in){}
    	~Leafmenu(){}
    	void showname()
    	{
    		cout<< "Leaf : " << name << endl;
    	}
    	virtual void Add(menu*){}
    	virtual void Remove(menu*){}
    };
    
    class Compositemenu : public menu
    {
    public:
    	Compositemenu(string in) : menu(in){}
    	void showname()
    	{
    		cout<< "Composit : "<< name << endl;
    		list<menu*>::iterator iter = m_child.begin();
    		while (iter != m_child.end())
    		{
    			(*iter)->showname();
    			iter++;
    		}
    	}
    	virtual void Add(menu*m){ m_child.push_back(m); }
    	virtual void Remove(menu*m){ m_child.remove(m); }
    private:
    	list<menu*> m_child;
    };
    //调用实现
    int main
    {
    	Compositemenu mainmenu("Main");
    
    	/***添加File菜单****/
    	Compositemenu *pFile = new Compositemenu("File");
    	Leafmenu *pNew = new Leafmenu("New");
    	Leafmenu *pOpen = new Leafmenu("Open");
    	Leafmenu *pClose = new Leafmenu("Close");
    	pFile->Add(pNew);
    	pFile->Add(pOpen);
    	pFile->Add(pClose);
    	mainmenu.Add(pFile);
    
    	/***添加Edit菜单****/
    	Compositemenu *pEdit = new Compositemenu("Edit");
    	Leafmenu *pCopy = new Leafmenu("Copy");
    	Leafmenu *pPaste = new Leafmenu("Paste");
    	pEdit->Add(pCopy);
    	pEdit->Add(pPaste);
    	mainmenu.Add(pFile);
    
    	Leafmenu *pExit = new Leafmenu("Exit");
    	Leafmenu *pHelp = new Leafmenu("Help");
    	mainmenu.Add(pExit);
    	mainmenu.Add(pHelp);
    
    	mainmenu.showname();
    
    	delete pNew;
    	delete pOpen;
    	delete pClose;
    	delete pFile;
    	delete pCopy;
    	delete pPaste;
    	delete pEdit;
    	delete pExit;
    	delete pHelp;
    }
    

    关于叶对节点的操作方法,如上面例子中add、remove、get等,其实是不需要的,因为基类申明的是纯虚函数,所以必须进行实现,但是在调用时没有任何意义,这就带来了一些使用的风险,安全的做法是将这些操作从基类中移除,添加到composite类中,这样在编译时就可以检查到调用问题,不过这样做显然又阻碍了接口的一致性,权衡利弊的选择还需自己根据需要来。

    应用场景

    常用的树形结构操作,如文件结构、菜单、组织结构等

  • 相关阅读:
    VIJOS-P1340 拯救ice-cream(广搜+优先级队列)
    uva 11754 Code Feat
    uva11426 GCD Extreme(II)
    uvalive 4119 Always an Interger
    POJ 1442 Black Box 优先队列
    2014上海网络赛 HDU 5053 the Sum of Cube
    uvalive 4795 Paperweight
    uvalive 4589 Asteroids
    uvalive 4973 Ardenia
    DP——数字游戏
  • 原文地址:https://www.cnblogs.com/chencarl/p/8669224.html
Copyright © 2011-2022 走看看