迭代器模式(Iterator Pattern)
迭代器模式定义: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)的更多相关文章
- 设计模式(十):从电影院中认识"迭代器模式"(Iterator Pattern)
上篇博客我们从醋溜土豆丝与清炒苦瓜中认识了“模板方法模式”,那么在今天这篇博客中我们要从电影院中来认识"迭代器模式"(Iterator Pattern).“迭代器模式”顾名思义就是 ...
- 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)
原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...
- 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)
设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...
- 二十四种设计模式:迭代器模式(Iterator Pattern)
迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现 ...
- 设计模式 - 迭代器模式(iterator pattern) 具体解释
迭代器模式(iterator pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 迭代器模式(iterator pattern) : 提供一 ...
- 设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素
模式概述 模式定义 模式结构图 模式伪代码 模式改进 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修 ...
- 16.迭代器模式(Iterator Pattern)
using System; namespace ConsoleApplication9 { class Program { /// <summary> /// 迭代器模式提供了一种方法顺序 ...
- C#设计模式——迭代器模式(Iterator Pattern)
一.概述在软件开发过程中,我们可能会希望在不暴露一个集合对象内部结构的同时,可以让外部代码透明地访问其中包含的元素.迭代器模式可以解决这一问题.二.迭代器模式迭代器模式提供一种方法顺序访问一个集合对象 ...
- [设计模式] 16 迭代器模式 Iterator Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对迭代器模式是这样说的:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示. 类图和实例: 迭代器模式由以下角 ...
随机推荐
- [swustoj 191] 迷宫逃离
迷宫逃离(0191) 描述 江鸟突然想到了一个迷宫逃离的游戏,话说有三个人被困于一个n*m的迷宫里,他们三人都可以向上.向下.向左.向右四个方向进行走动,当然他们所在的初始位置没有障碍物,同时只能走到 ...
- ☀【JS】Code
1 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf- ...
- cannot find the word template:WordToRqm.dot的解决方法
powerdesigner安装后: C:"Program Files"Sybase"PowerDesigner 12"Add-ins"Microsof ...
- 热修复 RocooFix篇(一)
吐槽之前先放一张大帅图. (md 这张图貌似有点小 不纠结这个了==) 有时候项目刚刚上线或者迭代 测试或者在线上使用测出一个bug来 真让人蛋疼 不得不重新改bug测试 打包混淆上线感觉就向find ...
- Android SDK 离线安装方法
有朋友反映从连接直接下载安装包不能获取到最新版本(每次更新后的包地址需要重新去查找),而且经常无法访问. 最方便的方法是使用代理或vpn接入网络,即可及时下载最新版sdk. 作为一名开发人员,流畅地浏 ...
- Html笔记(一)概述
Html就是超文本标记语言的简写,是最基础的网页语言 Html是通过标签来定义的语言,代码都是由标签所组成 Html代码不用区分大小写 Html代码由<html>开始</html&g ...
- linux和Dos下换行符转换
一.windows的文件到linux下的转换方法: 1. 用sed命令替换 sed -e 's/^M//g' original.txt > target.txt (注意^M 在Linux/Uni ...
- HW2.3
import java.util.Scanner; public class Solution { public static void main(String[] args) { final dou ...
- A Tour of Go Short variable declarations
Inside a function, the := short assignment statement can be used in place of a var declaration with ...
- php-fpm正在生成页面时,浏览器刷新后,php-fpm会退出吗?
好久没写博客了,因为没有啥可写. 之所以有此疑问,是因为看了一篇大牛的文章:PHP升级导致系统负载过高问题分析.看完后,其中有些文字触发了我这个想法,也想验证一下. 方案,用tcpdump抓包,用st ...