设计模式-迭代器模式
迭代器模式(Iterator Pattern)
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的表示。
迭代器模式结构:
抽象容器角色(Aggregate):负责提供创建具体迭代器角色的接口,一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
具体容器角色(ConcreteAggregate):就是实现抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkedList,Set接口的哈希列表的实现HashSet等。
抽象迭代器角色(Iterator):负责定义访问和遍历元素的接口。
具体迭代器角色(ConcreteIterator):实现迭代器接口,并要记录遍历中的当前位置。
代码:
//Aggregate:负责提供创建具体迭代器角色的接口,一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。 public interface Iterable{ public Iterator createIterator(); } public class Menu{ private String name; private String type; public String getName() {return name;} public void setName(String name) {this.name = name;} public String getType() {return type;} public void setType(String type) {this.type = type;} } //ConcreteAggregate:就是实现抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkedList,Set接口的哈希列表的实现HashSet等。 public class MorningMenu implements Iterable{ Menu[] menus; public MorningMenu() { this.menus = new Menu[10]; menus[0] = this.addMenu("油条","早餐"); menus[1] = this.addMenu("鸡蛋","早餐"); menus[2] = this.addMenu("豆腐脑","早餐"); } public Menu addMenu(String name,String type){ Menu menu = new Menu(); menu.setName(name); menu.setType(type); } public Menu[] getMenus(){ return menus; } @Override public Iterator createIterator() { return new MorningMenuIterator(menus); } } //ConcreteAggregate:就是实现抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkedList,Set接口的哈希列表的实现HashSet等。 public class EveningMenu implements Iterable{ List<Menu> menuList; public EveningMenu() { this.menuList = new ArrayList<>(); menuList.add(this.addMenu("米饭","晚餐")); menuList.add(this.addMenu("鱼香肉丝","晚餐")); menuList.add(this.addMenu("盖饭","晚餐")); } public Menu addMenu(String name,String type){ Menu menu = new Menu(); menu.setName(name); menu.setType(type); } public List<Menu> getMenuList(){eturn menuList;} @Override public Iterator createIterator() { return new EveningMenuIterator(menuList); } }
//Iterator:负责定义访问和遍历元素的接口。 public interface Iterator{ public boolean hasNext(); public Object next(); } //ConcreteIterator:实现迭代器接口,并要记录遍历中的当前位置。 public class MorningMenuIterator implements Iterator{ private int position = 0; private Menu[] menus; public MorningMenuIterator(Menu[] menus) {this.menus = menus;} @Override public boolean hasNext() { if(position>menus.length||menus[position]==null){ return false; } return true; } @Override public Object next() { Menu menu = menus[position]; position++; return menu; } } //ConcreteIterator:实现迭代器接口,并要记录遍历中的当前位置。 public class EveningMenuIterator implements Iterator{ private int position = 0; private List<Menu> menuList; public EveningMenuIterator(List<Menu> menuList) {this.menuList = menuList;} @Override public boolean hasNext() { if(CollectionUtils.isEmpty(menuList)){ return false; } return position<menuList.size(); } @Override public Object next() { Menu menu = menuList.get(position); position++; return menu; } }
//客户端调用 public class Test{ public static void main(String[] args){ MorningMenu morningMenu = new MorningMenu(); EveningMenu eveningMenu = new EveningMenu(); Iterator mornintIterator = morningMenu.createIterator(); Iterator eveningIterator = eveningMenu.createIterator(); this.print(mornintIterator); this.print(eveningIterator); } private void print(Iterator iterator){ while (iterator.hasNext()){ Menu menu = (Menu) iterator.next(); System.out.println(menu.getType()+menu.getName()); } } }
优点:
1、访问聚合对象内容时无需暴露其内部表示。
2、迭代器模式为不同的聚合结构对象提供了统一的接口。
3、在同一个聚合对象上可以实现多种遍历。
4、增加新的聚合类和迭代类较为方便,无需修改之前的代码。
缺点:
1、迭代器模式将存储数据和遍历数据的责任进行了分离。增加新的聚合类型的时候需要增加新的迭代器类。存在成对增加的。增加了系统的复杂性。
应用场景:
1、访问聚合对象的内容不需要暴露其内部表示。
2、需要为聚合对象提供多种遍历方式。
3、为了遍历不同的聚合结构对象提供统一的接口。