• 设计模式C++实现——组合模式


    模式定义:

            组合模式同意你将对象组合成树形结构来表现“总体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

            这个模式可以创建一个树形结构,在同一个结构中处理嵌套菜单和菜单项组。通过菜单和项放在同样结构中,我们创建了一个“总体/部分”层次结构,即由菜单和菜单项组成的对象树。使用组合结构,我们能把同样的操作应用在组合和个别对象上。换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的区别。

    模式结构:


    Component:

    为组合中的对象声明接口;

    在适当情况下实现全部类共同拥有接口的缺省行为。

    声明一个接口用于訪问管理Component的子组件

    在递归结构中定义一个接口,用于訪问一个父部件。并在合适的情况下实现它

    Leaf:

    在组合中表示叶节点对象,叶节点没有子节点,并定义其行为

    Composite:

    定义有子部件的那些部件的行为

    存储子部件

    实现与子部件有关的操作

    Client:

    通过Component接口操作组合件和个别对象。

    举例:

            在迭代器样例中,我们希望在午餐餐单中添加一份跌点餐单,也就是说希望能让甜点餐单变成午餐餐单的一个元素。

            我们能够用组合模式解决问题:一開始我们创建一个组件接口作为餐单和菜单项的共同接口。让我们能够用统一的做法来处理菜单和菜单项。

    换句话说,我们能够针对菜单或菜单项调用同样的方法。然后实现菜单项和组合菜单组件,以及他们各自的方法。

    UML设计:

    编程实现及运行结果:

    #include <iostream>
    #include <vector>
    #include <list>
    #include <string>
    
    using namespace std;
    
    //菜单和菜单项共同的组件
    class MenuComponent
    {
    public:
    	virtual void add(MenuComponent* menuComponent)
    	{
    		throw exception("add error!");
    	}
    
    	virtual void remove(MenuComponent* menuComponent)
    	{
    		throw exception("remove error!");
    	}
    
    	virtual MenuComponent* getChild(int i)
    	{
    		throw exception("getChild error");
    	}
    
    	virtual string getName()
    	{
    		throw exception("getName error");
    	}
    
    	virtual string getDescription()
    	{
    		throw exception("getDescription error");
    	}
    
    	virtual double getPrice()
    	{
    		throw exception("getPrice error");
    	}
    
    	virtual void print()
    	{
    		throw exception("print error");
    	}
    };
    
    //菜单项类
    class MenuItem : public MenuComponent
    {
    public:
    	MenuItem(){}
    	MenuItem(string na, string descrip, double pric)
    	{
    		name = na;
    		description = descrip;
    		price = pric;
    	}
    
    	string getName()
    	{
    		return name;
    	}
    
    	string getDescription()
    	{
    		return description;
    	}
    	
    	double getPrice()
    	{
    		return price;
    	}
    
    	void print()
    	{
    		cout << "	" << getName() << ",	" << getPrice() 
    			<<"	---" << getDescription() << endl;
    	}
    private:
    	string name;
    	string description;
    	double price;
    };
    //组合菜单类
    class Menu : public MenuComponent
    {
    public:
    	Menu(string nam, string descri)
    	{
    		name = nam;
    		description = descri;
    	}
    
    	void add(MenuComponent* pMenuComponent)
    	{
    		pMenuComponents.push_back(pMenuComponent);
    	}
    
    	void remove(MenuComponent* pMenuComponent)
    	{
    		vector<MenuComponent*>::iterator iter = pMenuComponents.begin();
    		for(; iter!=pMenuComponents.end(); ++iter)
    		{
    			if(*iter == pMenuComponent)
    			{
    				pMenuComponents.erase(iter);
    			}
    		}
    	}
    
    	MenuComponent* getChild(int i)
    	{
    		return pMenuComponents[i];
    	}
    
    	string getName()
    	{
    		return name;
    	}
    
    	string getDescription()
    	{
    		return description;
    	}
    
    	void print()
    	{
    		cout << endl << getName() << ",	" << getDescription() << endl << "--------------" << endl;
    		vector<MenuComponent*>::iterator iter = pMenuComponents.begin();
    		while(iter != pMenuComponents.end())
    		{
    			MenuComponent* pMenuComponent = *iter;
    			pMenuComponent->print();
    			++iter;
    		}
    	}
    private:
    	vector<MenuComponent*> pMenuComponents;
    	string name;
    	string description;
    };
    
    //服务生类
    class Waitress
    {
    public:
    	Waitress(MenuComponent* all_Menus)
    	{
    		allMenus = all_Menus;
    	}
    
    	void printMenu()
    	{
    		allMenus->print();
    	}
    private:
    	MenuComponent* allMenus;
    };
    //客户代码
    int main()
    {
    	MenuComponent* pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU", "Breakfast");
    	MenuComponent* dinerMenu = new Menu("Diner MENU", "Lunch");
    	MenuComponent* dessertMenu = new Menu("DESSERT MENU","Dessert of coure!");
    
    	MenuComponent* allMenus = new Menu("ALL Menus", "All menus combined");
    
    	allMenus->add(pancakeHouseMenu);
    	allMenus->add(dinerMenu);
    	dinerMenu->add(new MenuItem("Pasta","Spaheti with Sauce", 3.89));
    
    	dinerMenu->add(dessertMenu);
    	dessertMenu->add(new MenuItem("Apple Pie", "App pie with a cruse", 1.59));
    
    	Waitress* waitress = new Waitress(allMenus);
    	waitress->printMenu();
    	return 0;
    }
    


    运行结果:

     

    ALLMenus,      All menus combined

    --------------

    相关阅读:
    sharepoint email
    After delete Trigger throw error:The row value(s) updated or deleted either do not make the row unique or they alter multiple rows (2 rows).
    ios 开发书籍
    NES 指令
    nes相关开发资料
    nes相关开发资料
    怎样写模拟器
    Zope简介
    C#中new和override区别
    NES 指令

  • 原文地址:https://www.cnblogs.com/lytwajue/p/6960969.html
Copyright © 2020-2023  润新知