java 开发模式之十 : 迭代器模式
来源:互联网 发布:linux 下载命令 编辑:程序博客网 时间:2024/06/13 08:09
原理或定義
迭代器模式又叫做游标(Cursor)模式。GOF给出的定义:提供一种方法访问一个容器(container)对象中的各个元素,而又不暴露该对象的内部细节。
结构
迭代器角色(Iterator):负责定义访问和遍历元素的接口。
具体迭代器角色(Concrete Iterator):实现迭代器接口,并要记录遍历中的当前位置。
容器角色(Aggregate): 负责提供创建具体迭代器角色的接口。
具体容器角色(ConcreteAggregate):实现创建具体迭代器角色的接口,这个具体迭代器角色与该容器的结构相关。
類圖
案例与代码
本模式使用两个菜馆合并后的菜单问题来作为案例
蛋糕店与餐厅合并后,怎么统一管理菜单项目
问题:一个用ArrayList管理菜单,一个用数组管理
通用菜单类:
public class MenuItem {private String name,description;private boolean vegetable;private float price;public MenuItem(String name,String description,boolean vegetable,float price){this.name=name;this.description=description;this.vegetable=vegetable;this.price=price;}public String getName(){return name;}public String getDescription(){return description;}public float getPrice(){return price;}public boolean isVegetable(){return vegetable;}}
餐厅类:
public class CakeHouseMenu {private ArrayList<MenuItem> menuItems;public CakeHouseMenu() {menuItems = new ArrayList<MenuItem>();addItem("KFC Cake Breakfast","boiled eggs&toast&cabbage",true,3.99f);addItem("MDL Cake Breakfast","fried eggs&toast",false,3.59f);addItem("Stawberry Cake","fresh stawberry",true,3.29f);addItem("Regular Cake Breakfast","toast&sausage",true,2.59f);}private void addItem(String name, String description, boolean vegetable,float price) {MenuItem menuItem = new MenuItem(name, description, vegetable, price);menuItems.add(menuItem);}public ArrayList<MenuItem> getMenuItems() {return menuItems;}//其他功能代码}
public class DinerMenu {private final static int Max_Items=5;public int numberOfItems=0;private MenuItem[] menuItems;public DinerMenu(){menuItems=new MenuItem[Max_Items] ;addItem("vegetable Blt","bacon&lettuce&tomato&cabbage",true,3.58f);addItem("Blt","bacon&lettuce&tomato",false,3.00f);addItem("bean soup","bean&potato salad",true,3.28f);addItem("hotdog","onions&cheese&bread",false,3.05f);}private void addItem(String name, String description, boolean vegetable,float price) {MenuItem menuItem = new MenuItem(name, description, vegetable, price);if(numberOfItems>=Max_Items){System.err.println("sorry,menu is full!can not add another item");}else{menuItems[numberOfItems]=menuItem;numberOfItems++;}}public MenuItem[] getMenuItems() {return menuItems;}}
public class Waitress {private CakeHouseMenu mCakeHouseMenu;private DinerMenu mDinerMenu;private ArrayList<MenuItem> cakeitems;private MenuItem[] dineritems;public Waitress() {mCakeHouseMenu = new CakeHouseMenu();cakeitems = mCakeHouseMenu.getMenuItems();mDinerMenu = new DinerMenu();dineritems = mDinerMenu.getMenuItems();}public void printMenu() {MenuItem menuItem;for (int i = 0, len = cakeitems.size(); i < len; i++) {menuItem = cakeitems.get(i);System.out.println(menuItem.getName() + "***"+menuItem.getPrice()+"***"+ menuItem.getDescription());}for (int i = 0, len = mDinerMenu.numberOfItems; i < len; i++) {menuItem = dineritems[i];System.out.println(menuItem.getName() + "***"+menuItem.getPrice()+"***"+ menuItem.getDescription());}}public void printBreakfastMenu() {}public void printLunchMenu() {}public void printVegetableMenu() {}}
顾客 / 测试类:
public class MainTest {public static void main(String[] args) {Waitress mWaitress=new Waitress();//服务员展示2家餐厅合并的菜单mWaitress.printMenu();}}
此设计违法单一责任原则,当添加新餐厅,打印菜单的方法需要改变,而且复杂度和新餐厅的数据结构的复杂度成正比。
迭代器模式的设计方案:
通用菜单类不变。
迭代器角色(Iterator):
public interface Iterator {public boolean hasNext();public Object next();}
餐厅类:
public class CakeHouseMenu {private ArrayList<MenuItem> menuItems;public CakeHouseMenu() {menuItems = new ArrayList<MenuItem>();addItem("KFC Cake Breakfast","boiled eggs&toast&cabbage",true,3.99f);addItem("MDL Cake Breakfast","fried eggs&toast",false,3.59f);addItem("Stawberry Cake","fresh stawberry",true,3.29f);addItem("Regular Cake Breakfast","toast&sausage",true,2.59f);}private void addItem(String name, String description, boolean vegetable,float price) {MenuItem menuItem = new MenuItem(name, description, vegetable, price);menuItems.add(menuItem);}public Iterator getIterator(){return new CakeHouseIterator() ;}class CakeHouseIterator implements Iterator {private int position=0;public CakeHouseIterator(){ position=0;} @Overridepublic boolean hasNext() {// TODO Auto-generated method stubif(position<menuItems.size()){return true;}return false;}@Overridepublic Object next() {// TODO Auto-generated method stubMenuItem menuItem =menuItems.get(position);position++;return menuItem;}};//其他功能代码}public class DinerMenu {private final static int Max_Items = 5;private int numberOfItems = 0;private MenuItem[] menuItems;public DinerMenu() {menuItems = new MenuItem[Max_Items];addItem("vegetable Blt", "bacon&lettuce&tomato&cabbage", true, 3.58f);addItem("Blt", "bacon&lettuce&tomato", false, 3.00f);addItem("bean soup", "bean&potato salad", true, 3.28f);addItem("hotdog", "onions&cheese&bread", false, 3.05f);}private void addItem(String name, String description, boolean vegetable,float price) {MenuItem menuItem = new MenuItem(name, description, vegetable, price);if (numberOfItems >= Max_Items) {System.err.println("sorry,menu is full!can not add another item");} else {menuItems[numberOfItems] = menuItem;numberOfItems++;}}public Iterator getIterator() {return new DinerIterator();}class DinerIterator implements Iterator {private int position;public DinerIterator() {position = 0;}@Overridepublic boolean hasNext() {// TODO Auto-generated method stubif (position < numberOfItems) {return true;}return false;}@Overridepublic Object next() {// TODO Auto-generated method stubMenuItem menuItem = menuItems[position];position++;return menuItem;}};}
服务员类:public class Waitress {private ArrayList<Iterator> iterators=new ArrayList<Iterator>();public Waitress() {}public void addIterator(Iterator iterator){iterators.add(iterator);}public void printMenu() {Iterator iterator;MenuItem menuItem;for (int i = 0, len = iterators.size(); i < len; i++) {iterator = iterators.get(i);while(iterator.hasNext()){menuItem=(MenuItem)iterator.next();System.out.println(menuItem.getName() + "***"+menuItem.getPrice()+"***"+ menuItem.getDescription());}}}}
测试类:public class MainTest {public static void main(String[] args) {Waitress mWaitress=new Waitress();CakeHouseMenu mCakeHouseMenu = new CakeHouseMenu();DinerMenumDinerMenu = new DinerMenu();mWaitress.addIterator(mCakeHouseMenu.getIterator());mWaitress.addIterator(mDinerMenu.getIterator());mWaitress.printMenu();}}
该案例可以直接使用JDK内置的迭代器接口作为迭代器角色:Iterator
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个对象。
单一责任原则:一个类应该只有一个引起变化的原因.
使用場景
1. 访问一个聚合对象的内容而无需暴露它的内部表示
2.支持对聚合对象的多种遍历
3.为遍历不同的聚合结构提供一个统一的接口
優缺點
主要优点有:
1. 简化了遍历方式。
2.可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器。
3.封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。
缺点主要有:
对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合。
迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
- java 开发模式之十 : 迭代器模式
- java 开发模式之二十 :中介者模式
- java设计模式之十:模板模式
- Java开发中的23种设计模式之十:桥接模式(Bridge)
- Java开发中的23种设计模式之二十:状态模式(State)
- java之开发模式
- Java设计模式之十(观察者模式)
- Java设计模式之二十(迭代模式)
- (十)Java设计模式之代理模式
- (二十)Java设计模式之命令模式
- Java模式开发之责任链模式
- Java模式开发之责任链模式
- java开发模式之原型模式
- java 开发模式之二 : 观察者模式
- java 开发模式之五 : 工厂模式
- java 开发模式之六 : 命令模式
- java 开发模式之七 : 适配器模式
- java 开发模式之十二 : 状态模式
- 域名系统
- python装饰器后的函数名和文档变化
- 微信扫码支付asp
- Spring MVC
- 图像模糊有什么用
- java 开发模式之十 : 迭代器模式
- 【java 操作mysql】java连接mysql数据库并查询数据
- 使用pgrouting和geotools实现最短路径,服务区分析
- 听见丨苹果申请自主导航系统专利,自动驾驶汽车梦再近一步 现代打造更聪明、实用汽车AI语音系统
- 关于数据库事务的理解
- Cache与主存之间的全相联映射、直接映射和组相联映射的区别
- 【体验报告】好123影视体验报告
- Spring 思维导图,让 Spring 不再难懂(mvc篇)
- PKU 1017 Packets