迭代器模式(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的<设计模式:可复用面向对象软件的基础>一书中对迭代器模式是这样说的:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示. 类图和实例: 迭代器模式由以下角 ...
随机推荐
- hdu4662MU Puzzle
http://acm.hdu.edu.cn/showproblem.php?pid=4662 I+3*U模6为2或4的都可以 一个U相当于3个I 而I只能1->2->4->8..如 ...
- BZOJ_1612_[Usaco2008_Jan]_Cow_Contest_奶牛的比赛_(dfs)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1612 \(n\)头奶牛比赛,给出一些胜负情况,问可以确定多少头奶牛的排名. 分析 无论胜负,只 ...
- Samba nsswitch/pam_winbind.c文件输入验证漏洞
漏洞名称: Samba nsswitch/pam_winbind.c文件输入验证漏洞 CNNVD编号: CNNVD-201312-047 发布时间: 2013-12-05 更新时间: 2013-12- ...
- 转 脸书pop动画的五个步骤
http://blog.csdn.net/u013741809/article/details/38511741 5 Steps For Using Facebook Pop // 1. Pick ...
- ASP.NET MVC 開發心得分享 (21):Routing 觀念與技巧
ASP.NET MVC 預設在 Global.asax 所定義的 RegisterRoutes 方法中可以輕易的定義你希望擁有的網址格式,嚴格上來講這並非 ASP.NET MVC 的專利,而是從 AS ...
- HDU-1238 Substrings
Substrings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- HW3.21
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- HDU-1814 Peaceful Commission 2sat
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1814 简单的2sat题. //STATUS:C++_AC_390MS_996KB #include & ...
- 并查集 poj1611&poj2492
poj1611 简单题 代码中id记录父节点,sz记录子树规模.一个集合为一棵树. #include <iostream> #include <cstdio> using na ...
- CentOS上安装FastDFS分布式文件系统
鱼大自己写的项目简介:http://bbs.chinaunix.net/thread-1920470-1-1.html 架构简介:http://www.programmer.com.cn/4380/ ...