意图:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表现。
结构:
让我们看一下一个例子:
对乡村的餐厅和对象村的煎饼屋合并了。现在碰到一个棘手的问题,餐厅的菜单是使用Arraylist来实现,而煎饼屋的菜单是用数组来进行实现的,由于各自的菜单已经与其他过多的代码进行耦合,所以不能进行更改,现在有一个女Waitress,需要打印全部菜单,我们最初设想就是去分别遍历各自的菜单,但是如果添加以后我们需要第三种遍历方式。。
我们来看这样的缺点:
1.重复代码过多,都是过多的循环遍历,虽然每种遍历方式不同。
2.将菜单的实现暴露在外,耦合过高。
现在我们来看,按照上述结构我们画出的类图如下:
下面我们具体看一下代码,煎饼屋的代码:
首先是Inteactor接口我们使用java的api自带的:
然后我们来看煎饼屋的午餐迭代器的实现:
import java.util.Iterator; public class DinerMenuIterator implements Iterator { MenuItem[] list; int position = 0; public DinerMenuIterator(MenuItem[] list) { this.list = list; } public Object next() { MenuItem menuItem = list[position]; position = position + 1; return menuItem; } public boolean hasNext() { if (position >= list.length || list[position] == null) { return false; } else { return true; } } public void remove() { if (position <= 0) { throw new IllegalStateException ("You can't remove an item until you've done at least one next()"); } if (list[position-1] != null) { for (int i = position-1; i < (list.length-1); i++) { list[i] = list[i+1]; } list[list.length-1] = null; } } }
其中我们有一个menu的接口用于创建iterator:
public interface Menu { public Iterator createIterator(); }
接着我们看午餐的菜单是如何实现的:
public class DinerMenu implements Menu { static final int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; public DinerMenu() { menuItems = new MenuItem[MAX_ITEMS]; addItem("Vegetarian BLT", "(Fakin') 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 hot dog, with saurkraut, relish, onions, topped with cheese", false, 3.05); addItem("Steamed Veggies and Brown Rice", "Steamed vegetables over brown rice", true, 3.99); addItem("Pasta", "Spaghetti with Marinara Sauce, and a slice of sourdough bread", true, 3.89); } public void addItem(String name, String description, boolean vegetarian, double price) { MenuItem menuItem = new MenuItem(name, description, vegetarian, price); if (numberOfItems >= MAX_ITEMS) { System.err.println("Sorry, menu is full! Can't add item to menu"); } else { menuItems[numberOfItems] = menuItem; numberOfItems = numberOfItems + 1; } } public MenuItem[] getMenuItems() { return menuItems; } public Iterator createIterator() { return new DinerMenuIterator(menuItems); } // other menu methods here }
最后我们来看客户,也就是我们的女招待员是如何驱使这些菜单的:
import java.util.Iterator; public class Waitress { Menu pancakeHouseMenu; Menu dinerMenu; public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) { this.pancakeHouseMenu = pancakeHouseMenu; this.dinerMenu = dinerMenu; } public void printMenu() { Iterator pancakeIterator = pancakeHouseMenu.createIterator(); Iterator dinerIterator = dinerMenu.createIterator(); System.out.println("MENU\n----\nBREAKFAST"); printMenu(pancakeIterator); System.out.println("\nLUNCH"); printMenu(dinerIterator); } private void printMenu(Iterator iterator) { while (iterator.hasNext()) { MenuItem menuItem = (MenuItem)iterator.next(); System.out.print(menuItem.getName() + ", "); System.out.print(menuItem.getPrice() + " -- "); System.out.println(menuItem.getDescription()); } } public void printVegetarianMenu() { System.out.println("\nVEGETARIAN MENU\n----\nBREAKFAST"); printVegetarianMenu(pancakeHouseMenu.createIterator()); System.out.println("\nLUNCH"); printVegetarianMenu(dinerMenu.createIterator()); } public boolean isItemVegetarian(String name) { Iterator pancakeIterator = pancakeHouseMenu.createIterator(); if (isVegetarian(name, pancakeIterator)) { return true; } Iterator dinerIterator = dinerMenu.createIterator(); if (isVegetarian(name, dinerIterator)) { return true; } return false; } private void printVegetarianMenu(Iterator iterator) { while (iterator.hasNext()) { MenuItem menuItem = (MenuItem)iterator.next(); if (menuItem.isVegetarian()) { System.out.print(menuItem.getName()); System.out.println("\t\t" + menuItem.getPrice()); System.out.println("\t" + menuItem.getDescription()); } } } private boolean isVegetarian(String name, Iterator iterator) { while (iterator.hasNext()) { MenuItem menuItem = (MenuItem)iterator.next(); if (menuItem.getName().equals(name)) { if (menuItem.isVegetarian()) { return true; } } } return false; } }
这个就是我们客户的代码。
总结:
1.迭代器允许访问聚合元素,而不需要暴露它的内部结构。
2.迭代器将遍历聚合的工总封装到进另一个对象。
3.当使用迭代器的时候,我们依赖聚合提供遍历。
发表评论
-
《Head.First设计模式》的学习笔记(17)-综合例子
2012-02-12 00:53 0例子: -
《Head.First设计模式》的学习笔记(16)--复合模式
2012-02-12 00:51 0意图: -
《Head.First设计模式》的学习笔记(15)--代理模式
2012-02-13 00:03 1164意图: 为另一个对象提供一个替身或占位符得以访问这个对象。 ... -
《Head.First设计模式》的学习笔记(14)--状态模式
2012-02-12 20:24 1244意图:允许对象在内部状态改变时改变她的行为,对象看起来好像修改 ... -
《Head.First设计模式》的学习笔记(13)--组合模式
2012-02-12 17:49 845先说一下题外话,这个模式是我学的最累的模式,代码纠结无比,而且 ... -
《Head.First设计模式》的学习笔记(11)--模板方法模式
2012-02-12 00:46 883意图:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中 ... -
《Head.First设计模式》的学习笔记---前言
2012-02-11 23:36 0headfist系列博客从这篇--模版方法模式开始自己写的了, ... -
《Head.First设计模式》的学习笔记(10)--外观模式
2012-02-11 23:30 677意图:为子系统中的一组接口提供一个一致的界面,Facade ... -
《Head.First设计模式》的学习笔记(9)--适配器模式
2012-02-11 23:27 745软件开发中经常遇到的 ... -
《Head.First设计模式》的学习笔记(8)--命令模式
2012-02-11 22:55 741背景:有时候我们需要对方法进行封装,通过对这些封装的方法进行调 ... -
《Head.First设计模式》的学习笔记(7)--单件模式
2012-02-11 13:55 928背景:有一些对象其实我们只需要一个,比方说:线程池(threa ... -
《Head.First设计模式》的学习笔记(6)--抽象工厂模式
2012-02-11 13:37 852意图:提供一个接口,用于创建相关或依赖对象的家族,而不需要明 ... -
《Head.First设计模式》的学习笔记(5)--工厂方法模式
2012-02-10 23:58 763意图:定义一个用于创建对象的接口,让子类决定实例化哪一 ... -
《Head.First设计模式》的学习笔记(4)--装饰者模式
2012-02-10 23:40 808意图:动态地将责任 ... -
《Head.First设计模式》的学习笔记(3)--观察者模式
2012-02-10 23:27 732意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改 ... -
《Head.First设计模式》的学习笔记(2)--策略模式
2012-02-10 23:09 633先对策略模式有一个总体认识。 意图:定义一系列的算法,把它们 ... -
《Head.First设计模式》的学习笔记(1)
2012-01-31 21:53 7891、慢一点,你理解的越 ...
相关推荐
Head.First.设计模式-中文版-带目录Head.First.设计模式-中文版-带目录Head.First.设计模式-中文版-带目录Head.First.设计模式-中文版-带目录Head.First.设计模式-中文版-带目录
### Head.First 设计模式学习笔记知识点总结 #### 一、设计模式概述 设计模式是一种用于解决软件设计中常见问题的标准化方法。通过采用设计模式,开发者可以提高代码的复用性、灵活性和可维护性。《Head First 设计...
Head.First设计模式 Head.First设计模式Head.First设计模式 Head.First设计模式 Head.First设计模式
《HeadFirst设计模式学习笔记1--策略模式Demo》 在软件工程中,设计模式是一种解决常见问题的标准方案,它提供了一种在特定情况下组织代码的模板。策略模式是设计模式中的一种行为模式,它允许在运行时选择算法或...
在“HeadFirst 设计模式学习笔记3--装饰模式 Demo”中,作者通过实例讲解了装饰模式的基本概念、结构和应用场景。这篇文章可能是从CSDN博客平台上的一个链接访问的,遗憾的是,由于我们当前无法直接访问该链接,所以...
《Head First设计模式》是一本深受开发者喜爱的...以上就是《Head First设计模式》中37-78章的主要知识点,通过学习这些模式,开发者可以更好地理解和应用软件设计原则,提升代码质量,构建更健壮、更易维护的系统。
强大的写作阵容。本书作者Eric Freeman;ElElisabeth Freeman是作家、讲师和技术顾问。Eric拥有耶鲁大学的计算机科学博士学位,E1isabath拥有耶鲁大学的计算机科学硕士学位。... Head.First设计模式.part10.rar
强大的写作阵容。本书作者Eric Freeman;ElElisabeth Freeman是作家、讲师和技术顾问。Eric拥有耶鲁大学的计算机科学博士学位,E1isabath拥有耶鲁大学的计算机科学硕士学位。... Head.First设计模式.part10.rar
强大的写作阵容。本书作者Eric Freeman;ElElisabeth Freeman是作家、讲师和技术顾问。Eric拥有耶鲁大学的计算机科学博士学位,E1isabath拥有耶鲁大学的计算机科学硕士学位。... Head.First设计模式.part10.rar
强大的写作阵容。本书作者Eric Freeman;ElElisabeth Freeman是作家、讲师和技术顾问。Eric拥有耶鲁大学的计算机科学博士学位,E1isabath拥有耶鲁大学的计算机科学硕士学位。... Head.First设计模式.part10.rar
强大的写作阵容。本书作者Eric Freeman;ElElisabeth Freeman是作家、讲师和技术顾问。Eric拥有耶鲁大学的计算机科学博士学位,E1isabath拥有耶鲁大学的计算机科学硕士学位。... Head.First设计模式.part10.rar
总的来说,HeadFirst设计模式的学习笔记2关于观察者模式的演示,旨在帮助开发者理解如何使用观察者模式来构建可扩展的系统。通过实际的代码示例,我们可以更深入地掌握这一模式,并将其应用到日常开发中,提升代码的...