设计模式之迭代器与组合模式

来源:互联网 发布:淘宝组装电脑哪家好 编辑:程序博客网 时间:2024/04/30 14:45

OO餐厅和OO煎饼屋合并了,但是餐厅菜单实现采用数组,煎饼屋采用arraylist。

总的菜单类是这样的:

public class MenuItem {String name;String description;boolean vegetarian;double price;public MenuItem(String name,String description,boolean vegetarian,double price){this.name=name;this.description=description;this.vegetarian=vegetarian;this.price=price;}public String getName(){return name;}public String getDescription(){return description;}public double getPrice(){return price;}public boolean isVegetarian(){return vegetarian;}}

两家店的菜单实现:

import java.util.ArrayList;public class PancakeHouseMenu {ArrayList menuItems;public PancakeHouseMenu(){menuItems=new ArrayList<>();addItem("KB's pancake breakfast", "Pancakes with scrambled eggs and toast", true, 2.99);addItem("Regular pancake breakfast", "Pancakes with fried eggs,sausage ",false,2.99);addItem("Blueberry pancakes", "Pancakes made with fresh blueberry", true, 3.49);addItem("Waffles", "Waffles with your choice of blueberry or strawberry", true, 3.59);}public void addItem(String name,String description,booleanvegetarian,double price){MenuItem menuItem=new MenuItem(name, description, vegetarian, price);menuItems.add(menuItem);}public ArrayList getMenuItems(){return menuItems;}}

public class DinerMenu {static final int MAX_ITEMS=6;int numOfItems=0;MenuItem[] menuItems;public DinerMenu(){menuItems=new MenuItem[MAX_ITEMS];addItem("Vegetarian BLT", "Bacon with lettuce & tomato on whole wheat", true, 2.99);addItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99);addItem("Soup of the day", "Soup of the day.with a side of potato salad", false, 3.29);addItem("Hotdog", "A hotdog with saurkraut ,relesh,onions,topped with cheese",false,3.05);}public void addItem(String name,String description,boolean vegetarian,double price){MenuItem menuItem=new MenuItem(name, description, vegetarian, price);if(numOfItems>=MAX_ITEMS){System.err.println("Sorry,menu is full!Can't add item to menu.");}else {menuItems[numOfItems]=menuItem;numOfItems++;}}public MenuItem[] getMenuItem(){return menuItems;}}


两种不同的菜单表现方式会带来很多问题,比如女招待就遇到问题,printMenu()的话得调用两个menu的getMenuItem()方法,但是返回类型不一样,就得循坏一一列出item。


现在我们创建一个对象,将它称为迭代器Iterator,来封装“遍历集合内的每个对象的过程”。

Iterator iterator=breakfastMenu.createIterator();while(iterator.hasNext())    MenuItem menuItem=(MenuItem)iterator.next();

Iterator iterator=lunchMenu.createIterator();while(iterator.hasNext())    MenuItem menuItem=(MenuItem)iterator.next();

这时候女招待问题就可以解决了:

void  printMenu(Iterator iterator){    while(iterator.hasNext()){        MenuItem menuItem=(MenuItem)iterator.next();        //其他操作    }}



Java自带Iterator接口,ArrayList支持Iterator()方法,数组不支持,要自己定义,和之前不一样的是要实现remove()方法。



如果菜单又有子菜单怎么办?

定义组合模式,允许你将对象组合成树形结构来表现整体/部分层次结构。

首先实现菜单组件:


public abstract class MenuComponent {public void add(MenuComponent menuComponent){throw new UnsupportedOperationException();}public void remove(MenuComponent menuComponent){throw new UnsupportedOperationException();}public MenuComponent getCHild(int i){throw new UnsupportedOperationException();}public String getName(){throw new UnsupportedOperationException();}public String getDescription(){throw new UnsupportedOperationException();}public double getPrice(){throw new UnsupportedOperationException();}public boolean isVegetarian(){throw new UnsupportedOperationException();}public void print(){throw new UnsupportedOperationException();}}

接下来是菜单项类:

public class MenuItem extends MenuComponent{String name;String description;boolean vegetarian;double price;public MenuItem(String name,String description,boolean vegetarian,double price){this.name=name;this.description=description;this.vegetarian=vegetarian;this.price=price;}public String getName(){return name;}public String getDescription(){return description;}public double getPrice(){return price;}public boolean isVegetarian(){return vegetarian;}public void print(){System.out.println(" "+getName());if(isVegetarian())System.out.println("(v)");System.out.println(","+getPrice());System.out.println("     --"+getDescription());}}

实现组合菜单:

import java.util.ArrayList;public class Menu extends MenuComponent{ArrayList menuComponents=new ArrayList<>();String name;String description;public Menu(String name,String description){this.name=name;this.description=description;}public void add(MenuComponent menuComponent){menuComponent.add(menuComponent);}public void remove(MenuComponent menuComponent){menuComponent.remove(menuComponent);}public MenuComponent getChild(int i){return (MenuComponent)menuComponents.get(i);}public String getName(){return name;}public String getDescription(){return description;}//不覆盖getPrice()和isVegetarian()方法public void print(){System.out.println("\n"+getName());System.out.println(","+getDescription());System.out.println("------------------------------");}}

修正print()方法:

public void print(){System.out.println("\n"+getName());System.out.println(","+getDescription());System.out.println("------------------------------");Iterator iterator=menuComponents.iterator();while(iterator.hasNext()){MenuComponent menuComponent=(MenuComponent)iterator.next();menuComponent.print();}}


接下来是一种组合迭代器:

我们要为每个组件都加上createIterator()方法:

public class Menu extends MenuComponents{    //其他不需要改变        public Iterator createIterator(){        return new CompositeIterator(menuComponents.iterator());    }}

public class MenuItem extends MenuComponent{    //其他不需要改变        public Iterator createIterator(){        return new NullIerator();    }}

迭代器:

import java.util.Iterator;import java.util.Stack;public class CompositeIterator implements Iterator{Stack stack=new Stack<>();public CompositeIterator(Iterator iterator){stack.push(iterator);}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;}}public boolean hasNext(){if(stack.empty())return false;else {Iterator iterator=(Iterator)stack.peek();if(!iterator.hasNext()){stack.pop();return hasNext();}else {return true;}}}public void remove(){throw new UnsupportedOperationException();}}

空迭代器:

import java.util.Iterator;public class NullIterator implements Iterator{@Overridepublic boolean hasNext() {// TODO Auto-generated method stubreturn false;}@Overridepublic Object next() {// TODO Auto-generated method stubreturn null;}@Overridepublic void remove() {// TODO Auto-generated method stubthrow new UnsupportedOperationException();}}


to conclude

组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。

0 0
原创粉丝点击