供一种方法顺序访问一个聚合对象中的各类元素,而又不暴露该对象的内部表示。 java
迭代器模式使用的场景很明确,那就是封装遍历。数组
当业务要对你的对象中的某一数据结构进行遍历,一般有两种作法:安全
下面具体来看看怎么作。bash
经过一个业务场景进行说明,仍是使用Java代码作演示。数据结构
假设有一个两种菜单(系统菜单和业务菜单),需求是须要遍历这两种菜单。先来看看不使用迭代器模式有什么弊端。ide
加入先开发了业务菜单,数据结构是数组:函数
@Data public class BusinessMenu { private String[] menus = new String[3]; public BusinessMenu() { menus[0] = "业务菜单A"; menus[1] = "业务菜单B"; menus[2] = "业务菜单C"; } }
而后开发了系统菜单,这是数据结构换成了集合:工具
@Data public class SystemMenu { private List<String> menus = new ArrayList<>(); public SystemMenu() { menus.add("系统菜单1"); menus.add("系统菜单2"); menus.add("系统菜单3"); } }
而后实现遍历的客户端以下:spa
public class Client { public static void main(String[] args) { SystemMenu menus = new SystemMenu(); List<String> mlist = menus.getMenus(); printSystemMenu(mlist); System.out.println(); BusinessMenu buttons = new BusinessMenu(); String[] blist = buttons.getMenus(); printBusinessMenu(blist); } public static void printSystemMenu(List<String> mlist) { for (int i = 0; i < mlist.size(); i++) { System.out.println(mlist.get(i)); } } public static void printBusinessMenu(String[] blist) { for (int i = 0; i < blist.length; i++) { System.out.println(blist[i]); } } }
这种状况就是第二节说到的,把数据结构返回给调用者,让他去实现遍历,说的更确切一些,是让他去操做数据结构进行遍历。设计
这种作法有两个弊端:
如何使用迭代器模式解决这个问题呢?其实Java内部提供了迭代器接口,咱们也能够本身建立一个迭代器接口,具体以下。
我准备直接使用Java提供的迭代器接口实现,先来看看类图和代码:
代码以下:
// 系统菜单,实现了迭代器接口 public class SystemMenu implements Iterator<String> { // 私有化数据结构 private List<String> menus = new ArrayList<>(); // 私有化的索引 private int index; public SystemMenu() { menus.add("系统菜单1"); menus.add("系统菜单2"); menus.add("系统菜单3"); index = 0; } @Override public boolean hasNext() { // 判断集合是否还有元素 return index < menus.size(); } @Override public String next() { // 返回集合的元素 String name = menus.get(index); // 索引+1 index++; return name; } }
// 业务菜单,实现了迭代器接口 public class BusinessMenu implements Iterator<String> { // 私有化数据结构 private String[] menus = new String[3]; // 私有化的索引 private int index; public BusinessMenu() { menus[0] = "业务菜单A"; menus[1] = "业务菜单B"; menus[2] = "业务菜单C"; index = 0; } @Override public boolean hasNext() { // 判断数组是否还有元素 return index < menus.length; } @Override public String next() { // 返回数组中的元素 String name = menus[index]; // 索引+1 index++; return name; } }
public class Client { public static void main(String[] args) { printMenu(new SystemMenu()); System.out.println(); printMenu(new BusinessMenu()); } public static void printMenu(Iterator<String> iterator) { // 使用迭代器,循环输出 while(iterator.hasNext()) { System.out.println(iterator.next()); } } }
输出: 系统菜单1 系统菜单2 系统菜单3 业务菜单A 业务菜单B 业务菜单C
上面就是迭代器模式,很简单,咱们在平常开发中常常会使用到,许多的工具类都会提供迭代器让咱们进行遍历。
可是仍是说说如何解决了弊端:
迭代器模式提高了类的内聚性!
类的每一个责任都有改变的潜在区域。超过一个责任,意味着超过一个改变区域。
这个原则告诉咱们,尽可能让每个类保持单一责任。
内聚(Cohesion)这个术语,它用来度量一个类或者模块是否紧密地达到单一目的或责任。
当一个模块或一个类被设计成只支持一组相关的功能时,咱们说它具备高内聚;反之,当被设计成支持一组不相关的功能时,咱们说它具备低内聚。
内聚是一个比单一职责更广泛的概念,但二者其实关系是很密切的。遵照这个原则的类更容易有很高的凝聚力,并且比背负许多职责的低内聚类更容易维护。
以上就是我对迭代器模式的一些理解,有不足之处请你们指出,谢谢。