zoukankan      html  css  js  c++  java
  • 设计模式之迭代器模式浅析

    迭代器提供一种方式遍历集合,而又无需暴露集合的实现
    
    /**
     * 设计原则:
     *   单一原则:一个类应该只有一个引起变化的原因
     *   内聚--用来衡量一个类或者模块紧密的达到单一目的或责任
     *   高内聚--表示一个类或者模块只支持一个/一组相关功能
     * 
     * 迭代器模式:
     *   提供一种顺序访问聚合对象元素的方法,而又不暴露其内部元素
     * 迭代器将遍历聚合对象的任务封装到一个对象中。
     * 
     * 示例:
     *   咖啡厅菜单、煎饼屋早餐、中国菜午餐
     * 通过菜单接口 提供给客户统一的访问菜单项的方式 而不用知道菜单项的管理方式
     * 
     * 但是当我们想在菜单中嵌套菜单时 或者说有多层菜单嵌套时 就需要使用组合模式
     * @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 stub
    		items.add(menuItem);
    	}
    
    	@Override
    	public Iterator createIterator() {
    		// TODO Auto-generated method stub
    		return 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 stub
    		items.put(menuItem.getName(), menuItem);
    	}
    
    
    	@Override
    	public Iterator createIterator() {
    		// TODO Auto-generated method stub
    		return 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 stub
    		items[count++]=menuItem;
    	}
    
    
    	@Override
    	public Iterator createIterator() {
    		// TODO Auto-generated method stub
    		return 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;
    	}
    	
    	@Override
    	public boolean hasNext() {
    		// TODO Auto-generated method stub
    		return count<items.length;
    	}
    
    	@Override
    	public Object next() {
    		// TODO Auto-generated method stub
    		return items[count++];
    	}
    
    	@Override
    	public void remove() {
    		// TODO Auto-generated method stub
    		throw 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;
    	}
    	@Override
    	public 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 stub
    		for (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 stub
    		System.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 {
    
    	@Test
    	public 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("
    
    
    
    ");
    	
    	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的方式 更具有扩展性 


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

  • 相关阅读:
    1136 A Delayed Palindrome (algorithm reverse(ans.begin,ans.end))
    1141 PAT Ranking of Institutions PAT甲级
    最近点对 (迭代器访问数据)
    1146 Topological Order PAT 甲级
    1151 1151 LCA in a Binary Tree PAT 甲级
    jQuery的基本使用
    案例:移动端返回顶部效果
    移动端轮播图(原生JS写法)
    移动端特效
    本地存储
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275539.html
Copyright © 2011-2022 走看看