博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式C++实现——组合模式
阅读量:5069 次
发布时间:2019-06-12

本文共 3600 字,大约阅读时间需要 12 分钟。

模式定义:

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

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

模式结构:

Component:

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

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

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

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

Leaf:

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

Composite:

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

存储子部件

实现与子部件有关的操作

Client:

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

 

举例:

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

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

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

UML设计:

编程实现及运行结果:

#include 
#include
#include
#include
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
::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
::iterator iter = pMenuComponents.begin(); while(iter != pMenuComponents.end()) { MenuComponent* pMenuComponent = *iter; pMenuComponent->print(); ++iter; } }private: vector
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

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

转载于:https://www.cnblogs.com/lytwajue/p/6960969.html

你可能感兴趣的文章
【Machine Learning-2】Stanford Uni Open Course: Machine Learning -- Lecture 2 Note
查看>>
kettle利用参数遍历执行指定目录下的所有对象
查看>>
fps
查看>>
Android 自定义View修炼-自定义可动画展开收缩View的实现
查看>>
ORA-12541:TNS:no listener 客户端tnsnames.ora配置,以及服务端listener.ora配置
查看>>
C#多线程操作界面控件的解决方案(转)
查看>>
JS获得本月的第一天和最后一天
查看>>
如何使java中double类型不以科学计数法表示
查看>>
AES加密解密
查看>>
IIS与web.config配置优化
查看>>
Luogu3733 HAOI2017 八纵八横 线段树分治、线性基
查看>>
CI简单易用
查看>>
执行力的不够的系统解决方案
查看>>
ReactNative--复合组件
查看>>
iOS -- js与原生交互
查看>>
jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失...
查看>>
mysql-常用基础命令
查看>>
spring中各jar功能及jar包之间的依赖关系
查看>>
WPF学习(9)样式和行为
查看>>
poj-1503-java大数相加
查看>>