设计模式之迭代器模式浅析

来源:互联网 发布:通风管道设计绘制软件 编辑:程序博客网 时间:2024/06/05 11:54
迭代器提供一种方式遍历集合,而又无需暴露集合的实现
/** * 设计原则: *   单一原则:一个类应该只有一个引起变化的原因 *   内聚--用来衡量一个类或者模块紧密的达到单一目的或责任 *   高内聚--表示一个类或者模块只支持一个/一组相关功能 *  * 迭代器模式: *   提供一种顺序访问聚合对象元素的方法,而又不暴露其内部元素 * 迭代器将遍历聚合对象的任务封装到一个对象中。 *  * 示例: *   咖啡厅菜单、煎饼屋早餐、中国菜午餐 * 通过菜单接口 提供给客户统一的访问菜单项的方式 而不用知道菜单项的管理方式 *  * 但是当我们想在菜单中嵌套菜单时 或者说有多层菜单嵌套时 就需要使用组合模式 * @author Administrator * */


统一的接口 菜单类

package com.undergrowth.iterator;import java.util.Iterator;/** * 设计原则: *   单一原则:一个类应该只有一个引起变化的原因 *   内聚--用来衡量一个类或者模块紧密的达到单一目的或责任 *   高内聚--表示一个类或者模块只支持一个/一组相关功能 *  * 迭代器模式: *   提供一种顺序访问聚合对象元素的方法,而又不暴露其内部元素 * 迭代器将遍历聚合对象的任务封装到一个对象中。 *  * 示例: *   咖啡厅菜单、煎饼屋早餐、中国菜午餐 * 通过菜单接口 提供给客户统一的访问菜单项的方式 而不用知道菜单项的管理方式 *  * 但是当我们想在菜单中嵌套菜单时 或者说有多层菜单嵌套时 就需要使用组合模式 * @author Administrator * */public interface Menu {/** * 返回菜单项的迭代器 * @return */   public Iterator createIterator();   }

煎饼屋菜单

package com.undergrowth.iterator;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * 煎饼屋菜单  使用ArrayList存放菜单项 * @author Administrator * */public class PanCakeHouse implements Menu {List<MenuItem> items=new ArrayList<MenuItem>();public PanCakeHouse(){addMenuItem(new MenuItem("热干面", 10, "地道的武汉热干面", true));addMenuItem(new MenuItem("过桥米线", 8, "正宗的云南过桥米线", true));addMenuItem(new MenuItem("鸡蛋肠粉", 80, "广州的地道早餐", false));}private void addMenuItem(MenuItem menuItem) {// TODO Auto-generated method stubitems.add(menuItem);}@Overridepublic Iterator createIterator() {// TODO Auto-generated method stubreturn items.iterator();}}

中国菜菜单

package com.undergrowth.iterator;import java.util.HashMap;import java.util.Iterator;import java.util.Map;/** * 中餐 使用hashmap存储 菜单项 * @author Administrator * */public class ChineseFood implements Menu {Map<String, MenuItem> items=new HashMap<>();public ChineseFood(){addMenuItem(new MenuItem("宫保鸡", 45, "宫保鸡丁是川菜的代表菜,由鸡脯肉、干辣椒、花生米炒制而成,香辣好吃", false));addMenuItem(new MenuItem("糖醋里脊", 78, "糖醋里脊色泽红亮、酸甜可口、外酥里嫩", false));addMenuItem(new MenuItem("烤鸭", 80, "北京烤鸭,被誉为“天下美味”而驰名中外,它更以色泽红润,肉质细嫩,味道醇厚,肥而不腻的特色而享誉海内外", false));}private void addMenuItem(MenuItem menuItem) {// TODO Auto-generated method stubitems.put(menuItem.getName(), menuItem);}@Overridepublic Iterator createIterator() {// TODO Auto-generated method stubreturn items.values().iterator();}}

咖啡厅菜单

package com.undergrowth.iterator;import java.util.Iterator;/** * 咖啡厅菜单 使用数组存储菜单项 * @author Administrator * */public class CoffeeMenu implements Menu {MenuItem[] items;int count=0;public CoffeeMenu(){items=new MenuItem[5];addMenuItem(new MenuItem("拿铁咖啡", 100, "咖啡与牛奶的交融", true));addMenuItem(new MenuItem("越南咖啡", 200, "采用纯正的越南咖啡豆", true));addMenuItem(new MenuItem("美式咖啡", 80, "清新的风味中不失本香", true));addMenuItem(new MenuItem("爱尔兰咖啡", 220, "融入砂糖、爱尔兰酒", true));addMenuItem(new MenuItem("皇家咖啡", 280, "流传于宫廷之中", true));}private void addMenuItem(MenuItem menuItem) {// TODO Auto-generated method stubitems[count++]=menuItem;}@Overridepublic Iterator createIterator() {// TODO Auto-generated method stubreturn new CoffeeIterator(items);}}

咖啡厅菜单的迭代器

package com.undergrowth.iterator;import java.util.Iterator;/** * 将数组进行封装成迭代器 * @author Administrator * */public class CoffeeIterator implements Iterator {MenuItem[] items;int count;public CoffeeIterator(MenuItem[] items){this.items=items;count=0;}@Overridepublic boolean hasNext() {// TODO Auto-generated method stubreturn count<items.length;}@Overridepublic Object next() {// TODO Auto-generated method stubreturn items[count++];}@Overridepublic void remove() {// TODO Auto-generated method stubthrow new UnsupportedOperationException();}}

菜单项

package com.undergrowth.iterator;/** * 菜单项 * @author Administrator * */public class MenuItem {String name;float price;String description;boolean vegetarian;public MenuItem(String name, float price, String description,boolean vegetarian) {super();this.name = name;this.price = price;this.description = description;this.vegetarian = vegetarian;}@Overridepublic String toString() {return "MenuItem [name=" + name + ", price=" + price + ", description="+ description + ", vegetarian=" + vegetarian + "]";}public String getName() {return name;}public float getPrice() {return price;}public String getDescription() {return description;}public boolean isVegetarian() {return vegetarian;}}

服务员打印菜单

package com.undergrowth.iterator;import java.util.Iterator;/** * 服务员 用于打印菜单 * @author Administrator * */public class Waitress {Menu panMenu;Menu coffeeMenu;Menu chineseMenu;public Waitress(Menu panMenu, Menu coffeeMenu, Menu chineseMenu) {super();this.panMenu = panMenu;this.coffeeMenu = coffeeMenu;this.chineseMenu = chineseMenu;}public void printMenu(){System.out.println("==============开始打印菜单==============");System.out.println("   ===========开始打印咖啡菜单===========   ");Iterator<MenuItem> iteratorMenu=coffeeMenu.createIterator();printMenu(iteratorMenu);System.out.println("   ===========结束打印咖啡菜单===========   ");System.out.println("   ===========开始打印中国菜菜单===========   ");iteratorMenu=chineseMenu.createIterator();printMenu(iteratorMenu);System.out.println("   ===========结束打印中国菜菜单===========   ");System.out.println("   ===========开始打印煎饼屋菜单===========   ");iteratorMenu=panMenu.createIterator();printMenu(iteratorMenu);System.out.println("   ===========结束打印煎饼屋菜单===========   ");System.out.println("==============结束打印菜单==============");}private void printMenu(Iterator<MenuItem> iteratorMenu) {// TODO Auto-generated method stubfor (Iterator iterator = iteratorMenu; iterator.hasNext();) {MenuItem miItem = (MenuItem) iterator.next();System.out.println(miItem);}}}

为了更好的扩展 使用List存放菜单 上面类的变体

package com.undergrowth.iterator;import java.util.Iterator;import java.util.List;import com.undergrowth.adapter.EnumeIteratorAdapter;/** * 服务员 用于打印菜单 为了更易于扩展 使用List存放菜单 * @author Administrator * */public class WaitressList {List<Menu> menus;public WaitressList(List<Menu> menus) {super();this.menus = menus;}public void printMenu(){System.out.println("==============开始打印菜单==============");Iterator<Menu> menusIterator=menus.iterator();while(menusIterator.hasNext()){Menu menu=menusIterator.next();printMenu(menu.createIterator());}System.out.println("==============结束打印菜单==============");}private void printMenu(Iterator<MenuItem> iteratorMenu) {// TODO Auto-generated method stubSystem.out.println("   ===========开始打印新菜单===========   ");for (Iterator iterator = iteratorMenu; iterator.hasNext();) {MenuItem miItem = (MenuItem) iterator.next();System.out.println(miItem);}System.out.println("   ===========结束打印新菜单===========   ");}}

测试

package com.undergrowth.iterator.test;import static org.junit.Assert.*;import java.util.ArrayList;import java.util.List;import org.junit.Test;import com.undergrowth.iterator.ChineseFood;import com.undergrowth.iterator.CoffeeMenu;import com.undergrowth.iterator.Menu;import com.undergrowth.iterator.PanCakeHouse;import com.undergrowth.iterator.Waitress;import com.undergrowth.iterator.WaitressList;public class WaitressTest {@Testpublic void test() {    Menu panMenu = new PanCakeHouse();Menu coffeeMenu = new CoffeeMenu();Menu chineseMenu = new ChineseFood();Waitress waitress=new Waitress(panMenu, coffeeMenu, chineseMenu);    waitress.printMenu();System.out.println("\n\n\n\n");List<Menu> menus=new ArrayList<>();menus.add(panMenu);menus.add(coffeeMenu);menus.add(chineseMenu);WaitressList waitressList=new WaitressList(menus);waitressList.printMenu();}}

结果输出

==============开始打印菜单==============   ===========开始打印咖啡菜单===========   MenuItem [name=拿铁咖啡, price=100.0, description=咖啡与牛奶的交融, vegetarian=true]MenuItem [name=越南咖啡, price=200.0, description=采用纯正的越南咖啡豆, vegetarian=true]MenuItem [name=美式咖啡, price=80.0, description=清新的风味中不失本香, vegetarian=true]MenuItem [name=爱尔兰咖啡, price=220.0, description=融入砂糖、爱尔兰酒, vegetarian=true]MenuItem [name=皇家咖啡, price=280.0, description=流传于宫廷之中, vegetarian=true]   ===========结束打印咖啡菜单===========      ===========开始打印中国菜菜单===========   MenuItem [name=宫保鸡, price=45.0, description=宫保鸡丁是川菜的代表菜,由鸡脯肉、干辣椒、花生米炒制而成,香辣好吃, vegetarian=false]MenuItem [name=糖醋里脊, price=78.0, description=糖醋里脊色泽红亮、酸甜可口、外酥里嫩, vegetarian=false]MenuItem [name=烤鸭, price=80.0, description=北京烤鸭,被誉为“天下美味”而驰名中外,它更以色泽红润,肉质细嫩,味道醇厚,肥而不腻的特色而享誉海内外, vegetarian=false]   ===========结束打印中国菜菜单===========      ===========开始打印煎饼屋菜单===========   MenuItem [name=热干面, price=10.0, description=地道的武汉热干面, vegetarian=true]MenuItem [name=过桥米线, price=8.0, description=正宗的云南过桥米线, vegetarian=true]MenuItem [name=鸡蛋肠粉, price=80.0, description=广州的地道早餐, vegetarian=false]   ===========结束打印煎饼屋菜单===========   ==============结束打印菜单============================开始打印菜单==============   ===========开始打印新菜单===========   MenuItem [name=热干面, price=10.0, description=地道的武汉热干面, vegetarian=true]MenuItem [name=过桥米线, price=8.0, description=正宗的云南过桥米线, vegetarian=true]MenuItem [name=鸡蛋肠粉, price=80.0, description=广州的地道早餐, vegetarian=false]   ===========结束打印新菜单===========      ===========开始打印新菜单===========   MenuItem [name=拿铁咖啡, price=100.0, description=咖啡与牛奶的交融, vegetarian=true]MenuItem [name=越南咖啡, price=200.0, description=采用纯正的越南咖啡豆, vegetarian=true]MenuItem [name=美式咖啡, price=80.0, description=清新的风味中不失本香, vegetarian=true]MenuItem [name=爱尔兰咖啡, price=220.0, description=融入砂糖、爱尔兰酒, vegetarian=true]MenuItem [name=皇家咖啡, price=280.0, description=流传于宫廷之中, vegetarian=true]   ===========结束打印新菜单===========      ===========开始打印新菜单===========   MenuItem [name=宫保鸡, price=45.0, description=宫保鸡丁是川菜的代表菜,由鸡脯肉、干辣椒、花生米炒制而成,香辣好吃, vegetarian=false]MenuItem [name=糖醋里脊, price=78.0, description=糖醋里脊色泽红亮、酸甜可口、外酥里嫩, vegetarian=false]MenuItem [name=烤鸭, price=80.0, description=北京烤鸭,被誉为“天下美味”而驰名中外,它更以色泽红润,肉质细嫩,味道醇厚,肥而不腻的特色而享誉海内外, vegetarian=false]   ===========结束打印新菜单===========   ==============结束打印菜单==============




对比 可以发现 使用List的方式 更具有扩展性 


迭代器提供一种方式遍历集合,而又无需暴露集合的实现

0 0