组合模式
来源:互联网 发布:python做服务器 编辑:程序博客网 时间:2024/05/18 05:31
组合模式
允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
这个模式能够创建一个树形结构,在同一个结构中处理嵌套菜单和菜单项组。通过将菜单和项放在相同的结构中,我们创建了一个“整体/部分”层次结构,即由菜单和菜单项组成的对象树,但是可以将它视为一个整体,像是一个大菜单。
这是一个树形结构
graph LRnote-->leat1note-->leat2note-->leat3
带子元素的元素成为节点(node)
没有子元素的元素成为叶节点(leat)
==组合模式让我们能用树形结构创建对象的结构,树里面包含了组合以及个别的对象。==
==使用组合结构,我们能他相同的操作应用在组合和个别的对象上,换句话说,子啊大多数情况下,我们可以++忽略++对象组合和个别对象之间的差别。==
利用组合设计菜单
需要创建一个组件接口来作为菜单和菜单项的共同接口,让我们能够用统一的做法来处理菜单和菜单项。
实现菜单组件
菜单组件的角色为叶节点和组合节点提供一个共同的接口。
==所以的组件都必须实现MenuComponent接口,然而,叶节点和组合节点的角色不同,所以有些方法可能并不适合某些节点,面对这种情况,有时候,你最好是抛出运行时异常。==
/** * @author lzlj21@163.com * 对每个方法都提供默认的实现 * 因为有些方法只对菜单项有意义,而有些方法只对菜单有有意, * 默认实现时抛出UnsupportedOperationException * 异常,这样,如果菜单项或菜单不支持某个操作,他们就不需要做任何事情,直接继承默认实现就可以了。 */public abstract class MenuComponent { /** * * @param component * * 新增菜单 * */ public void add(MenuComponent component){ throw new UnsupportedOperationException(); } /** * @param component * * 删除菜单 */ public void remove(MenuComponent component){ throw new UnsupportedOperationException(); } /** * @param i * * 取得菜单组件 */ public void getChild(int i){ throw new UnsupportedOperationException(); } /** * 菜单项操作 * * */ public String getName(){ throw new UnsupportedOperationException(); } public String getDescripion(){ throw new UnsupportedOperationException(); } public boolean isVegetarian(){ throw new UnsupportedOperationException(); } /** * 打印 */ public void print(){ throw new UnsupportedOperationException(); }}
实现菜单项
/** * @author lzlj21@163.com * * 菜单项 * */public class MenuItem extends MenuComponent { String name; String description; String vegetarian; double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getVegetarian() { return vegetarian; } public void setVegetarian(String vegetarian) { this.vegetarian = vegetarian; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } /* (实现菜单打印) * @see com.tkn.fdemo.menu.MenuComponent#print() * */ @Override public void print() { System.out.println(" "+getName()); if (isVegetarian()) { System.out.println("{v}"); } System.out.println(", "+getPrice()); System.out.println(" --- "+getDescripion()); }}
实现组合菜单
/** * @author lzlj21@163.com * 菜单 * */public class Menu extends MenuComponent { ArrayList memuComponents=new ArrayList<>(); String name; String description; public Menu(String name, String description) { this.name = name; this.description = description; } @Override public void add(MenuComponent component) { memuComponents.add(component); } @Override public void remove(MenuComponent component) { memuComponents.remove(component); } @Override public MenuComponent getChild(int i) { return (MenuComponent) memuComponents.get(i); } /* (non-Javadoc) * @see com.tkn.fdemo.menu.MenuComponent#print() * 用迭代器遍历所以菜单 */ @Override public void print() { System.out.println(getName()); System.out.println(", "+getDescripion()); System.out.println("------------------"); Iterator iterator = memuComponents.iterator(); while(iterator.hasNext()){ MenuComponent menuComponent = (MenuComponent)iterator.next(); menuComponent.print(); } }}
女招待(测试准备)
public class Waitress { MenuComponent allMenu; public Waitress(MenuComponent allMenu) { super(); this.allMenu = allMenu; } public void printMenu(){ allMenu.print(); }}
测试
public class MenuTestDrive { public static void main(String[] args) { /** * 定义菜单 */ MenuComponent pancakHouseMenu=new Menu("pancake", "breakfase"); MenuComponent pancakHouseMenu1=new Menu("pancake1", "breakfase1"); MenuComponent pancakHouseMenu2=new Menu("pancake2", "breakfase2"); MenuComponent pancakHouseMenu3=new Menu("pancake3", "breakfase3"); MenuComponent pancakHouseMenu4=new Menu("pancake4", "breakfase4"); MenuComponent allMenus=new Menu("all menus", "all menus cobined"); /** * 全部菜单添加到根菜单 */ allMenus.add(pancakHouseMenu); allMenus.add(pancakHouseMenu1); allMenus.add(pancakHouseMenu2); allMenus.add(pancakHouseMenu3); allMenus.add(pancakHouseMenu4); MenuComponent menuItem=new MenuItem("apple","apaple pie",true,11.2); // 添加菜单项 pancakHouseMenu4.add(menuItem); // 添加全部菜单 Waitress waitress=new Waitress(allMenus); // 打印菜单 waitress.printMenu(); }}
组合模式为什么违反了单一责任
==组合模式以单一责任设计原则换取透明性==
通过让组件的接口同时包含一些管理子节点和叶节点的操作,客户就可以将组合和叶节点一视同仁。也就是说,一个元素究竟是组合还是叶节点,对客户是透明的。
组合迭代器
public abstract class MenuComponent { //其他部分代码 //添加组合调用的方法 abstract createIterator();}
public class MenuItem extends MenuComponent { //其他部分代码 public Iterator createIterator{ return new NullIteartor(); }}
public class Menu extends MenuComponent { //其他部分代码 public Iterator createIterator{ return new ComPositeIteator(menuComponents.iterator()); }}
/** * @author lzlj21@163.com * 组合迭代器 * 实现了util.Iterator接口 */public class CompositeIterator implements Iterator { //堆栈数据 Stack stack =new Stack<>(); /** * @param iterator * 将要遍历的顶层组合的迭代器传入,抛进堆栈数据结构中 * */ public CompositeIterator(Iterator iterator) { stack.push(iterator); } @Override public boolean hasNext() { /** * 判断堆栈中是否还有数据 */ if (stack.empty()) { return false; }else{ /** * 从堆栈的顶层取出迭代器,看看是否还有下一个元素,如果他没有元素, * 我们将它弹出 ,然后递归的调用hasNext() * 否则我们将返回true */ Iterator iterator=(Iterator) stack.peek(); if (!iterator.hasNext()) { stack.pop(); return hasNext(); }else{ return true; } } } @Override public Object next() { // 判断是否还有下一个数据 if (hasNext()) { /** * 如果还有下一个,取出目前的迭代器,然后取出他的下一个元素 */ Iterator iterator=(Iterator) stack.peek(); MenuComponent component = (MenuComponent)iterator.next(); /** * 如果是一个菜单元素,就有了另一个需要被包含进遍历中的组合, * 所以需要把它丢进堆栈中, * 不管是不是菜单我们都返回组件 */ if (component instanceof Menu) { stack.push(component.createIterator()); } return component; }else { return null; } }}
阅读全文
0 0
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 【教程】html+css零基础入门教程之类选择器详解(二十六)
- H5页面如何适配iPhone X ?腾讯设计师给出了通用解决方案!
- 行业奇葩:不接受996加班制?现在员工吃不了苦啊!
- VIM常用快捷键
- 1、Tensorflow:Windows10+tensorflow1.4
- 组合模式
- 圆桌聚餐
- PAT
- Ubuntu搭建ss shadowsocks服务错误
- 线性回归
- 让滚动条滚动到正好显示某个节点的位置
- 73. Set Matrix Zeroes
- MariaDB基本管理操作
- nested exception is java.lang.IllegalArgumentException: error at ::0 formal