Head First设计模式(阅读笔记)-11.组合模式
创始人
2024-03-24 17:54:53
0

继续修改菜单

在迭代器模式中往菜单中加入了迭代器,但是存在一个问题服务员在打印菜单时,每次增加一份菜单就要修改代码,违反开闭原则:

public void printMenu(){Iterator pancakeIterator = pancakeHouseMenu.createIterator();Iterator cafeIterator = cafeMenu.createIterator();printMenu(pancakeIterator);printMenu(cafeIterator);
}

为什么不尝试将所有菜单放入一个集合中?

public class Waitress{ArrayList menus;  // 统一到一个菜单集合中,该菜单集合包含多种菜单public Waitress(ArrayList menus){this.menus = menus;}public void printMenu(){// 在菜单集合上进行遍历Iterator menuIterator = menus.iterator();while(menuIterator.hasNext()){Menu menu = (Menu)menuIterator.next();printMenu(menu.createIterator());}}private void printMenu(Iterator iterator){while(iterator.hasNext()){MenuItem item = (Menuitem)iterator.next();// 打印操作,此处省略}}
}

上述方法很好解决了问题,但是此时要在咖啡厅菜单中加入一个甜点菜单,这个甜点菜单是一份单独的菜单,并不是将甜点项(菜单项)添加到咖啡厅菜单中,该如何实现?


组合模式

  • 允许将对象组合为树形结构来表现整体/部分层次结构,树中包含了组合以及个别对象(即叶子节点和非叶子节点)
  • 组合能让客户通过一致的方式处理个别对象和对象组合(即实现相同的接口)

实现菜单组件

菜单组件可以是某个菜单项(叶子节点),也可以是某个菜单(组合,也就是非叶子节点)


public abstract class MenuComponent{// 下面方法有些只对菜单项(叶子节点)有意义,有些只对菜单(组合,也就是非叶子节点)有意义,所以默认实现抛出异常public void add(MenuComponent menuComponent){  // 新增菜单组件throw new UnsupporteOperationException();}public void remove(MenuComponent menuComponent){  // 删除菜单组件throw new UnsupporteOperationException();}public MenuComponent getChild(int i){  // 获取菜单组件throw new UnsupporteOperationException();}// 还有getName、getPrice等方法,此处省略
}

实现菜单项


public class MenuItem extends MenuComponent{String name;double price;public MenuItem(String name, double price){this.name = name;this.price = price;}// 还有getName、getPrice方法,此处省略public void print(){// 打印菜品名称和价格,此处省略}
}

实现组合菜单

对于组合菜单还可以有多个菜单项(叶子节点)以及其他菜单(即子树)


public class Menu extends MenuComponent{ArrayList menuComponents = new ArrayList();  // 可以有任意数目的孩子,但是都必须是MenuComponent类型String name;String desc;public MenuItem(String name, String desc){this.name = name;this.desc = desc;}public void add(MenuComponent menuComponent){menuComponents.add(menuComponent);}public void remove(MenuComponent menuComponent){menuComponents.remove(menuComponent);}public MenuComponent getChild(int i){return (MenuComponent)menuComponents.get(i);}// 还有getName、getDesc方法,此处省略public void print(){// 打印菜单名称和描述,此处省略// 除了菜单本身信息,还要打印出菜单中所有组件的信息(即其他菜单和菜单项)Iterator iterator = menuComponents.iterator();while(iterator.hasNext()){MenuComponent menuComponent = (MenuComponent)iterator.next();menuComponent.print();  // 递归调用}}
}

修改服务员代码

把最顶层的菜单组件(即整个树的根节点)给服务员


public class Waitress{MenuComponent rootmenu;  // 将根节点的交给服务员即可public Waitress(MenuComponent rootmenu){this.rootmenu = rootmenu;}public void printMenu(){rootmenu.print();}
}

测试


public class MenuTest{public static void main(String[] agrs){// 定义菜单组件(根节点也是菜单组件)MenuComponent cafeMenu = new Menu("CAFE MENU", "Dinner");        		 MenuComponent pancakeHouseMenu = new Menu("PNCAKE HOUSE MENU", "Breakfast");MenuComponent dessertMenu = new Menu("DESSRET MENU", "Anytime");MenuComponent rootMenu = new Menu("ALL MENUS", "All menus combined");// 开始构建树// 1.添加子树rootMenu.add(cafeMenu);rootMenu.add(pancakeHouseMenu);// 2.往子树中添加叶子节点或其他子树cafeMenu.add(dessertMenu);  // 实现开始的目标:往咖啡厅菜单中添加甜点菜单cafeMenu.add(new MenuItem("BLACK COFFEE", 25));  // 咖啡厅肯定需要咖啡的// 把完整菜单给服务员Waitress waitress = new Waitress(rootMenu);  waitress.printMenu();}
}

已学模式


模式描述
适配器模式改变一个或多个接口
迭代器模式提供一个方式遍历集合,且无需暴露集合的实现
外观模式简化一群类的接口
组合模式客户可将对象的集合和个别对象一视同仁
观察者模式当某个对象改变时,允许一群对象被通知

参考

Head First 设计模式-组合模式

设计模式-组合模式

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...