迭代器模式定义:Iterator Pattern提供一种方法顺序访问一个聚合元素中的各个元素,而又不暴漏内部方法

酒吧提供beer和wine:

public class Bar {
private List<String> barMenu; public Bar(){
barMenu = new ArrayList<String>();
barMenu.add("beer");
barMenu.add("wine");
} public List<String> getMenu(){
return barMenu;
}
}

餐厅提供rice、soup和noodles:

public class Restaurant {
private String[] restaurantMenu; public Restaurant(){
restaurantMenu = new String[3];
restaurantMenu[0] = "rice";
restaurantMenu[1] = "soup";
restaurantMenu[2] = "noodles";
} public String[] getMenu(){
return restaurantMenu;
}
}

现在要将酒吧与餐厅整合为一个点餐系统,在该点餐系统中既能看到酒吧的所有饮品,又能看到餐厅的所有餐点,通常的处理方式为:

public class OrderSystem {
private Bar bar;
private Restaurant reataurant; public OrderSystem(Bar bar,Restaurant reataurant){
this.bar = bar;
this.reataurant = reataurant;
} public void printMenu(){
List<String> bMenus = bar.getMenu();
String[] rMenus = reataurant.getMenu();
if(null != bMenus && bMenus.size() > 0){
for(String name : bMenus){
System.out.println(name);
}
}
if(null != rMenus){
for(int i = 0;i < rMenus.length; i++){
if(null != rMenus[i]){
System.out.println(rMenus[i]); }
}
}
}

1,OrderSystem类与具体集合类型(String[]以及List<String>)、具体实现(for循环)耦合

2,OrderSystem类与具体餐厅类耦合,即使这两个餐厅类提供的方法相同

先来考虑问题1,显然我们需要进行封装以隐藏具体集合类型与实现过程

从OrderSystem类中可以看出,其对集合的操作为遍历,那么封装类需要提供方法以使我们可以遍历其封装的不同集合

public interface Iterator {
public boolean hasNext(); public Object next() throws Exception;
}
public class BarIterator implements Iterator {
private List<String> menu;
int nextPosition = 0; public BarIterator(List<String> menu){
this.menu = menu;
} public boolean hasNext() {
if(menu.size() > nextPosition && null != menu.get(nextPosition)){
return true;
}
return false;
} public Object next() throws Exception {
if(menu.size() > nextPosition && null != menu.get(nextPosition)){
Object result = menu.get(nextPosition);
nextPosition++;
return result;
}
throw new Exception("越界");
}
}
public class RestaurantIterator implements Iterator {
private String[] menu;
int nextPosition = 0; public RestaurantIterator(String[] menu){
this.menu = menu;
} public boolean hasNext() {
if(menu.length > nextPosition && null != menu[nextPosition]){
return true;
}
return false;
} public Object next() throws Exception {
if(menu.length > nextPosition && null != menu[nextPosition]){
Object result = menu[nextPosition];
nextPosition++;
return result;
}
throw new Exception("越界");
}
}
public class Bar {
private List<String> barMenu; public Bar(){
barMenu = new ArrayList<String>();
barMenu.add("beer");
barMenu.add("wine");
} public Iterator getMenu(){
return new BarIterator(barMenu);
}
}
public class Restaurant {
private String[] restaurantMenu; public Restaurant(){
restaurantMenu = new String[3];
restaurantMenu[0] = "rice";
restaurantMenu[1] = "soup";
restaurantMenu[2] = "noodles";
} public RestaurantIterator getMenu(){
return new RestaurantIterator(restaurantMenu);
}
}
public class OrderSystem {
private Bar b;
private Restaurant r; public OrderSystem(Bar b,Restaurant r){
this.b = b;
this.r = r;
} public void printMenu(){
Iterator bit = b.getMenu();
Iterator rit = r.getMenu();
printMenu(bit);
printMenu(rit);
} private void printMenu(Iterator it){
try{
while(it.hasNext()){
Object tmp = it.next();
if(null != tmp){
System.out.println(tmp.toString());
}
}
}catch(Exception e){
System.out.println(e.getMessage());
}
} public static void main(String[] args){
Bar b = new Bar();
Restaurant r = new Restaurant();
OrderSystem h = new OrderSystem(b,r);
h.printMenu();
}
}

封装的遍历方法没有加锁,在多线程环境下是不适用的

看看设计中的Iterator类是不是和java.util.Iterator十分相似?

/*
* @(#)Iterator.java 1.27 06/07/24
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/ package java.util; /**
* An iterator over a collection. Iterator takes the place of Enumeration in
* the Java collections framework. Iterators differ from enumerations in two
* ways: <ul>
* <li> Iterators allow the caller to remove elements from the
* underlying collection during the iteration with well-defined
* semantics.
* <li> Method names have been improved.
* </ul><p>
*
* This interface is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @author Josh Bloch
* @version 1.27, 07/24/06
* @see Collection
* @see ListIterator
* @see Enumeration
* @since 1.2
*/
public interface Iterator<E> {
/**
* Returns <tt>true</tt> if the iteration has more elements. (In other
* words, returns <tt>true</tt> if <tt>next</tt> would return an element
* rather than throwing an exception.)
*
* @return <tt>true</tt> if the iterator has more elements.
*/
boolean hasNext(); /**
* Returns the next element in the iteration.
*
* @return the next element in the iteration.
* @exception NoSuchElementException iteration has no more elements.
*/
E next(); /**
*
* Removes from the underlying collection the last element returned by the
* iterator (optional operation). This method can be called only once per
* call to <tt>next</tt>. The behavior of an iterator is unspecified if
* the underlying collection is modified while the iteration is in
* progress in any way other than by calling this method.
*
* @exception UnsupportedOperationException if the <tt>remove</tt>
* operation is not supported by this Iterator. * @exception IllegalStateException if the <tt>next</tt> method has not
* yet been called, or the <tt>remove</tt> method has already
* been called after the last call to the <tt>next</tt>
* method.
*/
void remove();
}

再来考虑问题2:与具体餐厅类耦合很容易处理-面向接口编程

这里使用java.util.Iterator

不想实现的方法就抛出默认异常,上面的Iterator类源代码中说的很清楚了:

public class RestaurantIterator implements Iterator<String> {
private String[] menu;
int nextPosition = 0; public RestaurantIterator(String[] menu){
this.menu = menu;
} public boolean hasNext() {
if(menu.length > nextPosition && null != menu[nextPosition]){
return true;
}
return false;
} public String next(){
if(menu.length > nextPosition && null != menu[nextPosition]){
String result = menu[nextPosition];
nextPosition++;
return result;
}
throw new NoSuchElementException();
} public void remove(){
throw new UnsupportedOperationException();
}
}
public interface R {
public Iterator<String> getMenu();
}
public class Bar implements R{
private List<String> barMenu; public Bar(){
barMenu = new ArrayList<String>();
barMenu.add("beer");
barMenu.add("wine");
} public Iterator<String> getMenu(){
return barMenu.iterator();
}
}
public class Restaurant implements R{
private String[] restaurantMenu; public Restaurant(){
restaurantMenu = new String[3];
restaurantMenu[0] = "rice";
restaurantMenu[1] = "soup";
restaurantMenu[2] = "noodles";
} public Iterator<String> getMenu(){
return new RestaurantIterator(restaurantMenu);
}
}
public class OrderSystem {
private Bar b;
private Restaurant r; public OrderSystem(Bar b,Restaurant r){
this.b = b;
this.r = r;
} public void printMenu(){
Iterator<String> bit = b.getMenu();
Iterator<String> rit = r.getMenu();
printMenu(bit);
printMenu(rit);
} private void printMenu(Iterator<String> it){
try{
while(it.hasNext()){
Object tmp = it.next();
if(null != tmp){
System.out.println(tmp.toString());
}
}
}catch(Exception e){
System.out.println(e.getMessage());
}
} public static void main(String[] args){
Bar b = new Bar();
Restaurant r = new Restaurant();
OrderSystem h = new OrderSystem(b,r);
h.printMenu();
}
}

List可以自动返回一个封装好的Iterator

    /**
* Returns an iterator over the elements in this list in proper sequence.
*
* @return an iterator over the elements in this list in proper sequence
*/
Iterator<E> iterator();

迭代器模式(Iterator Pattern)的更多相关文章

  1. 设计模式(十):从电影院中认识"迭代器模式"(Iterator Pattern)

    上篇博客我们从醋溜土豆丝与清炒苦瓜中认识了“模板方法模式”,那么在今天这篇博客中我们要从电影院中来认识"迭代器模式"(Iterator Pattern).“迭代器模式”顾名思义就是 ...

  2. 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)

    原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...

  3. 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)

    设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...

  4. 二十四种设计模式:迭代器模式(Iterator Pattern)

    迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现 ...

  5. 设计模式 - 迭代器模式(iterator pattern) 具体解释

    迭代器模式(iterator pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 迭代器模式(iterator pattern) : 提供一 ...

  6. 设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素

    模式概述 模式定义 模式结构图 模式伪代码 模式改进 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修 ...

  7. 16.迭代器模式(Iterator Pattern)

    using System; namespace ConsoleApplication9 { class Program { /// <summary> /// 迭代器模式提供了一种方法顺序 ...

  8. C#设计模式——迭代器模式(Iterator Pattern)

    一.概述在软件开发过程中,我们可能会希望在不暴露一个集合对象内部结构的同时,可以让外部代码透明地访问其中包含的元素.迭代器模式可以解决这一问题.二.迭代器模式迭代器模式提供一种方法顺序访问一个集合对象 ...

  9. [设计模式] 16 迭代器模式 Iterator Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对迭代器模式是这样说的:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示. 类图和实例: 迭代器模式由以下角 ...

随机推荐

  1. [Hadoop源码解读](四)MapReduce篇之Counter相关类

    当我们定义一个Counter时,我们首先要定义一枚举类型: public static enum MY_COUNTER{ CORRUPTED_DATA_COUNTER, NORMAL_DATA_COU ...

  2. XmlNode中Value和InnerText的区别

    XmlNode中Value和InnerText的区别   这个问题我想很多人在使用.NET 操作 Xml 文档时都遇到过,先看一下MSDN里对这两个属性的解释: XmlNode.Value:获取或设置 ...

  3. android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)

    Android实现上拉加载更多功能以及下拉刷新功能, 采用了目前比较火的PullToRefresh,他是目前实现比较好的下拉刷新的类库. 目前他支持的控件有:ListView, ExpandableL ...

  4. 对 Linux 专家非常有用的 20 个命令

    原文链接:http://www.oschina.net/translate/20-advanced-commands-for-linux-experts?from=20130811 对中级 Linux ...

  5. [原]H264帧内预测

    帧内预测模块大小 说明 4x4(亮度) 预测方式9种 8x8(亮度) 预测方式9种.只有high profile才有 16x16(亮度) 预测方式4种,只依赖左,上数据. 8x8(色度) 预测方式4种 ...

  6. 微软Azure 存储管理器的简单介绍

    Windows Azure存储用户经常希望能够在“管理器”中查看他们的数据,管理器指的是一款可用于显示存储帐户数据的工具.我们之前提供了我们所知的存储管理器列表.在本文中,我们将对此列表进行更新,使其 ...

  7. git日常操作

    0.准备工作 0.1 git安装 http://git-scm.com/download/   图形客户端建议使用source tree,中文界面 http://www.sourcetreeapp.c ...

  8. HW5.1

    public class Solution { public static void main(String[] args) { int count = 0; for(int i = 1; i < ...

  9. A Tour of Go Slices

    A slice points to an array of values and also includes a length. []T is a slice with elements of typ ...

  10. iOS的UILabel设置居上对齐,居中对齐,居下对齐

    在iOS中默认的UILabel中的文字在竖直方向上只能居中对齐,博主参考国外网站,从UILabel继承了一个新类,实现了居上对齐,居中对齐,居下对齐.具体如下: // //  myUILabel.h ...