迭代器模式定义: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. URAL1029. Ministry(DP+路径)

    链接 路径麻烦啊 很多细节 倒回去搜一遍 卡了一节数据库.. #include <iostream> #include<cstdio> #include<cstring& ...

  2. poj2411Mondriaan's Dream(状压)

    http://poj.org/problem?id=2411 下次还是去学习下dfs的写法吧 自己乱写的好像有点乱 乱七八糟改了一通过了 以1 1 表示横着的 1 0 表示竖着的 枚举每一行的状态 再 ...

  3. Atom 扩展离线安装

    1.下载原始包 2.解压放入atom的packages文件夹中 3.通过nodejs的npm指令进行安装 运行->cmd 4.重启Atom就ok了

  4. 指尖下的js ——多触式web前端开发之一:对于Touch的处理

    指尖下的js ——多触式web前端开发之一:对于Touch的处理 水果公司的那些small and cute的设备给我们提供了前所未有的用户体验.当用户在iphone和ipad上运指如飞的时候,那些使 ...

  5. Go Hello World!

    有些事应该坚持去做 当你半途而废的时候意味着你又要重新开始.那么 Golang Hello world! Java Android 新手 学习 Golang  First Day ! go 语言下载: ...

  6. CodeForces 370A Rook, Bishop and King

    此题看似很简单,但实际上有不少细节,WA点不少.分情况处理即可. #include<cmath> #include<cstdio> #include<string> ...

  7. JSP---JavaBean的使用-jsp:useBean标签相关

    JavaBean介绍: JavaBean其实就是一个遵循特定写法的java类,但是必须具有如下特点: 1.这个java类必须具有一个公开的无参构造函数 2.属性必须私有化,类必须公开 3.私有化的属性 ...

  8. 华为过滤字符串(java)

    /*通过键盘输入一串小写字母(a~z)组成的字符串.请编写一个字符串过滤程序,若字符串中出现多个相同的字符,将非首次出现的字符过滤掉.比如字符串“abacacde”过滤结果为“abcde”.要求实现函 ...

  9. 数据中心基础设施自动化运维之puppet专项

    http://forge.puppetlabs.com/treydock/yum_cron  [puppet功能扩展forge] http://docs.puppetlabs.com/referenc ...

  10. Java 下 SSL 通信原理及实例

    有关SSL的原理和介绍在网上已经有不少,对于Java下使用keytool生成证书,配置SSL通信的教程也非常多.但如果我们不能够亲自动手做一个SSL Sever和SSL Client,可能就永远也不能 ...