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类中,这样在编译时就可以检查到调用问题,不过这样做显然又阻碍了接口的一致性,权衡利弊的选择还需自己根据需要来。

    应用场景

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

  • 相关阅读:
    es6学习笔记
    vue.js项目目录结构说明
    js 数组操作总结
    js 数组去重方法
    HTTP协议三次握手过程
    MVC与MVVM模式对比
    谱面编辑器
    LL谱面分析和难度标定
    SLP的模块结构
    LL基本姿势
  • 原文地址:https://www.cnblogs.com/chencarl/p/8669224.html
Copyright © 2011-2022 走看看