专栏首页java程序员思维java设计模式之迭代器模式,顾客永远的上帝

java设计模式之迭代器模式,顾客永远的上帝

迭代器模式

迭代器模式(Iterator Pattern)提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。这种类型的设计模式属于行为型模式。

迭代器模式解决的问题

对于不同类型的集合,使用同一种方式进行遍历,客户端不需要关心服务端的内部实现方式。

迭代器模式模式角色

抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。

具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。

抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。

具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

使用场景

需要为聚合对象提供多种遍历方式时。

需要为遍历不同的聚合结构提供一个统一的接口时。

访问一个聚合对象的内容而无须暴露其内部细节的表示。

迭代器方法类型

hasNext方法:是否还存在元素

next方法:下一个元素对象

代码实现

打印各班级的名单,1班老师用的是数组存储,2班老师用的是List

/**
 * 打印各班级的名单,1班老师用的是数组存储,2班老师用的是List
 */
public class BadCode {
 private String class1[] = {"java程序员思维", "java", "设计模式", "迭代器模式"};
 private List<String> class2 = Arrays.asList(class1);
 private void printAllName() {
 //打印1班的学生姓名
 System.out.println("1班学生姓名");
 for (String name : class1) {
 System.out.println(name);
 }
 System.out.println("-----------------");
 System.out.println("2班学生姓名");
 //打印2班的学生姓名
 for (String name : class2) {
 System.out.println(name);
 }
 }
 public static void main(String[] args) {
 BadCode badCode = new BadCode();
 badCode.printAllName();
 }
}

运行结果:

上面的代码是一个比较糟糕的实现,客户端明确的直到了服务端的具体实现,还有一个问题是如果有一个新的班级,老师用的是HashMap来存储,客户端的代码需要被重新修改,不支持开闭原则,我们对以上的代码进行改进。

/**
 * 迭代器
 */
public interface Iterator {
 public boolean hasNext();
 public Object next();
}
//数组存储
public class NameArrayIterator implements Iterator {
 public String names[] = {"java程序员思维", "java", "设计模式", "迭代器模式"};
 private int index = 0;
 public boolean hasNext() {
 if (index < names.length) {
 return true;
 }
 return false;
 }
 public Object next() {
 if (this.hasNext()) {
 return names[index++];
 }
 return null;
 }
}
//list存储
public class NameListIterator implements Iterator {
 private List<String> arrayList;
 private int index = 0;
 public NameListIterator() {
 arrayList = new ArrayList<String>();
 arrayList.add("java程序员思维");
 arrayList.add("java");
 arrayList.add("设计模式");
 arrayList.add("迭代器模式");
 }
 public boolean hasNext() {
 if(index < arrayList.size()){
 return true;
 }
 return false;
 }
 public Object next() {
 Object object = arrayList.get(index);
 index++;
 return object;
 }
}
public class Client {
 private Iterator iterator;
 public Client(Iterator iterator) {
 this.iterator = iterator;
 }
 public void printName(){
 while (iterator.hasNext()){
 System.out.println(iterator.next().toString());
 }
 }
 public Iterator getIterator() {
 return iterator;
 }
 public void setIterator(Iterator iterator) {
 this.iterator = iterator;
 }
}
public class IteratorPatternTest {
 public static void main(String[] args) {
 NameArrayIterator nameArrayIterator = new NameArrayIterator();
 Client client = new Client(nameArrayIterator);
 System.out.println("使用数组存储" );
 client.printName();
 System.out.println("----------------------------");
 NameListIterator nameListIterator = new NameListIterator();
 client.setIterator(nameListIterator);
 System.out.println("使用List存储" );
 client.printName();
 }
}

使用迭代器模式,隐藏了服务端的代码实现,同时使用了策略模式,当有新的实现,也满足开闭原则,不需要修改客户端代码。

运行结果:

JDK和框架中的迭代器模式

public Iterator<E> iterator() {
 return new ArrayList.Itr();
}

public Iterator<E> iterator() {
 return this.map.keySet().iterator();
}

jdk中的java.util包下的Iterator,使用的就是迭代器模式,ArrayList、HashSet等都提供了iterator方法,获取迭代器。

优缺点

优点:隐藏了聚合对象的内部实现,提供统一的方式遍历聚合对象。

缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

生活中的命令模式

迭代器有点像平台,定义的统一的入口,所有的商家都按照平台的规则,每个商家都有自己的店铺页,用户可以在商家店铺中,浏览商家的所有商品。天猫、京东、美团、饿了么等等,微信小程序,也提供了一个迭代器,能方便用户找到对应商家的应用服务,无需下载相应的app,打开即用。

我的启发

迭代器模式,提供一套标准,让用户无需关心具体的实现细节,用统一的方式给用户提供最便捷的服务,用户填好自己的收货地址、下完单付完款,就可以坐等第二天收快递,以至于商家发什么快递,顺丰、圆通、中通,用户并没有那么关心。顾客是上帝,请给我提供最简单,最省心的服务。

设计模式系列文章历史

java设计模式之模板模式,站在巨人的肩膀上成功

java设计模式之适配器模式,大丈夫能屈能伸

Head First 设计模式之命令模式,各司其职提高效率

Head First 设计模式之装饰器模式,因为参与,所以认同

Head First 设计模式之单例模式,每个人都是唯一

Head First 设计模式之观察者模式,你我都是发布者和订阅者

Head first 设计模式之策略模式,来源于生活,用之于生活

本文分享自微信公众号 - java程序员思维(java_python_go),作者:曾建路

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java设计模式之代理模式,看我72

    代理模式(Proxy Pattern)一个类代表另一个类的功能,通过代理对象访问目标对象,可以在目标对象实现的基础上,增强额外的功能。

    用户4361942
  • Head First 设计模式之装饰器模式,因为参与,所以认同

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包...

    用户4361942
  • Head First 设计模式之命令模式,各司其职提高效率

    命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的...

    用户4361942
  • Flash/Flex学习笔记(30):不用startDrag和stopDrag的对象拖动

    对于从Sprite类继承来的对象,要实现拖放当然是Flash/Flex学习笔记(13):对象拖动(startDrag/stopDrag) 里讲的方法最方便,但是...

    菩提树下的杨过
  • 设计模式实战-迭代器模式

    迭代器是为容器服务的,那什么是容器呢? 能容纳对象的所有类型都可以称之为容器,例如Collection集合类型、Set类型等,迭代器模式就是为解决遍历这些容器中...

    JavaEdge
  • Java实现动态代理的两种方式

    Java领域中,常用的动态代理实现方式有两种,一种是利用JDK反射机制生成代理,另外一种是使用CGLIB代理。

    朝雨忆轻尘
  • ABP框架学习之——授权(Authorization)

    易兒善
  • 设计模式-备忘录模式

    cwl_java
  • WCF技术剖析之十七:消息(Message)详解(上篇)

    消息交换是WCF进行通信的唯一手段,通过方法调用(Method Call)形式体现的服务访问需要转化成具体的消息,并通过相应的编码(Encoding)才能通过传...

    蒋金楠
  • 4.26 VR扫描:育碧投资AR和区块链游戏;《枪墓VR完全版》即将登陆PSVR

    VRPinea

扫码关注云+社区

领取腾讯云代金券