设计模式第九集——组合模式(Composite Pattern)
组合模式:利用组合模式可以将对象组合成树形结构来表现“整体/部分”层次结构。组合能让用户以一致的方式处理个别对象以及对象组合。
比如图形界面,Frame或Panel是顶层组件包含其它组件(例如菜单、蚊子面板、滚动条、按钮)这样这个GUI包含了若干部分,当显示的时候认为是一个整体,告诉顶层组件显示,由顶层组件显示左右相关部分。这个包含其它组件的组件为组合对象,成没有包含其它组件的组件为叶节点。
例如,餐厅有多种餐单(咖啡厅餐单、甜点餐单等等)餐单还有子餐单成树形结构。
代码:
MenuComponent
1 package com; 2 3 public abstract class MenuComponent { 4 //组合的方法 5 public void add(MenuComponent menuComponent){ 6 throw new UnsupportedOperationException(); 7 } 8 public void remove(MenuComponent menuComponent){ 9 throw new UnsupportedOperationException(); 10 } 11 public MenuComponent getChile(int i){ 12 throw new UnsupportedOperationException(); 13 } 14 //操作方法 15 public String getName(){ 16 throw new UnsupportedOperationException(); 17 } 18 public String getDescription(){ 19 throw new UnsupportedOperationException(); 20 } 21 public double getPrice(){ 22 throw new UnsupportedOperationException(); 23 } 24 public void print(){ 25 throw new UnsupportedOperationException(); 26 } 27 }
MenuItem
1 package com; 2 3 public class MenuItem extends MenuComponent { 4 String name; 5 String description; 6 double price; 7 8 public MenuItem(String name, String description, double price) { 9 10 this.name = name; 11 this.description = description; 12 this.price = price; 13 } 14 15 public String getName() { 16 return name; 17 } 18 19 public String getDescription() { 20 return description; 21 } 22 23 public double getPrice() { 24 return price; 25 } 26 public void print(){ 27 System.out.println(" "+getName()); 28 System.out.println(", "+getPrice()); 29 System.out.println(" -- "+getDescription()); 30 } 31 32 33 34 }
Menu:
1 package com; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; 5 6 public class Menu extends MenuComponent { 7 ArrayList menuComponents = new ArrayList(); 8 String name; 9 String description; 10 11 public Menu(String name, String description) { 12 this.name = name; 13 this.description = description; 14 } 15 16 @Override 17 public void add(MenuComponent menuComponent) { 18 // TODO Auto-generated method stub 19 menuComponents.add(menuComponent); 20 } 21 22 @Override 23 public void remove(MenuComponent menuComponent) { 24 // TODO Auto-generated method stub 25 menuComponents.remove(menuComponent); 26 } 27 28 public MenuComponent getChile(int i) { 29 // TODO Auto-generated method stub 30 return (MenuComponent) menuComponents.get(i); 31 } 32 33 @Override 34 public String getName() { 35 // TODO Auto-generated method stub 36 return name; 37 } 38 39 @Override 40 public String getDescription() { 41 // TODO Auto-generated method stub 42 return description; 43 } 44 45 @Override 46 public void print() { 47 System.out.println("\n" + getName()); 48 System.out.println(", " + getDescription()); 49 System.out.println("--------------------"); 50 51 // 用迭代器 遍历所有餐单组件 若果在遍历中遇到了其他餐单或者遇到菜单项 52 // 调用print() 53 Iterator iterator = menuComponents.iterator(); 54 while (iterator.hasNext()) { 55 MenuComponent menuComponent = (MenuComponent) iterator.next(); 56 menuComponent.print(); 57 } 58 } 59 60 }
Waiteress
package com; public class Waitress { MenuComponent allMenus; public Waitress(MenuComponent allMenus) { this.allMenus = allMenus; } public void printMenu(){ allMenus.print(); } }
Test:
1 package com; 2 3 public class test { 4 public static void main(String args[]){ 5 MenuComponent pancakeHouseMenu=new Menu("Pancake House Menu","Breakfast"); 6 MenuComponent dinerMenu=new Menu("Diner Menu","Lunch"); 7 MenuComponent CaffeeMenu=new Menu("Caffee Menu","Caffee"); 8 MenuComponent desertMenu=new Menu("Desert Menu","Desert"); 9 //加入餐单 10 MenuComponent allMenus=new Menu("All Menus","All Menus combined"); 11 allMenus.add(pancakeHouseMenu); 12 allMenus.add(dinerMenu); 13 allMenus.add(CaffeeMenu); 14 allMenus.add(desertMenu); 15 16 //加入餐单中的具体内容 17 dinerMenu.add(new MenuItem("Pasta","Apaghetti with Marinara",3.89)); 18 //在dinerMenu中加入另一个餐单desertMenu 19 dinerMenu.add(desertMenu); 20 desertMenu.add(new MenuItem("Apple Pie","Apple Pie",1.12)); 21 22 Waitress waitress =new Waitress(allMenus); 23 waitress.printMenu(); 24 } 25 26 }