JAVA23种设计模式之迭代器模式

  1. 迭代器模式
    提供一种方法来顺序访问一个聚合对象中各个元素,而又无需暴露该对象的内部表示。
    首先解释下什么叫做聚合对象,就)是可以存储多个成员的元素或者是对象的的类。一般情况下,聚合对象主要是用来存储数据和和遍历书,这样就可以联想到JAVA中的list,数组,HashSet等等。这些确实都是聚合对象。这里就存在个问题,就是当我们要遍历不同类型的聚合对象时,就要清楚的知道其结构,毕竟不同结构的聚合对象遍历的方式有区别。但是如果我们使用了迭代器模式,就不需要知道每个聚合对象的内部结构,而可以很方便快捷的遍历不同聚合对象的内部成员。
  2. 迭代模式示例图
    迭代器模式
  3. 迭代器模式设计角色:
  • 抽象迭代器角色:这是迭代器模式中最终要的角色,一般为抽象类或者是接口的形式。从经验来说一般包括三个方法hasNext()next()remove()三个方法。该角色定义了访问和遍历元素的接口。
  • 具体迭代器角色:继承或者实现了抽象迭代器角色。并且实现了其中的方法。
  • 抽象聚合角色:一般是一个接口,用于定义创建迭代器的方法。
  • 具体聚合角色:实现抽象聚合角色,并且创建相应的迭代器。
  1. 迭代器模式的示例代码
    场景:一家早餐馆收购了一家晚餐馆,合并后发现两家店的菜单系统由于之前设计的问题,存在相当大的差异,早餐店使用的是数组作为存储结构,晚餐店使用的是list作为存储结构。现在需求是打印出两个菜单。
    抽象迭代器角色:
    public interface Iterator {
        boolean hasNext();
        Object next();
        void remove(Object item);
}

具体迭代器角色:
早餐厅迭代器角色:

public class BreakfastIterator implements Iterator {
    private Object[] items = new Object[5];
    private int position;
    public BreakfastIterator(Object[] items) {
        this.items = items;
        this.position = 0;
    }
    @Override
    public boolean hasNext() {
        if (position<items.length){
            return true;
        }
        return false;
    }
    @Override
    public Object next() {
        Object obj = items[position];
        if (position>5){
            throw new IndexOutOfBoundsException("菜单只有五项!");
        }else{
            position++;
        }
        return obj;
    }
    @Override
    public void remove(Object item) {
        Object[] objects = new Object[5];
        for (int i = 0; i <items.length ; i++) {
                if (!items[i].equals(item)){
                    objects[i] = items[i];
                }
        }
        items = objects;
    }
}

晚餐厅具体迭代器角色:

public class DinnerIterator implements Iterator {
    private List<Object> list;
    private int position ;
    public DinnerIterator(List<Object> list) {
        this.list = list;
        this.position = 0;
    }
    @Override
    public boolean hasNext() {
        if (position < list.size()){
            return true;
        }
        return false;
    }
    @Override
    public Object next() {
        Object menuItem = list.get(position);
        position++;
        return menuItem;
    }
    @Override
    public void remove(Object item) {
        list.remove(item);
    }
}

抽象聚合角色:

public interface Aggregate {
    Iterator createIterator();
}

具体聚合角色:

public class BreakFastMeun implements Aggregate {
    private MenuItem[] menuItems ;
    private int num=0;
    public BreakFastMeun() {
        menuItems = new MenuItem[3];
       addMeunItem(new MenuItem("包子",1.5f));
       addMeunItem(new MenuItem("馒头",1f));
       addMeunItem(new MenuItem("粽子",5f));
    }
    @Override
    public Iterator createIterator() {
        return new BreakfastIterator(menuItems);
    }
    public void addMeunItem(MenuItem menuItem){
        if (num >= menuItems.length) {
            System.err.println("sorry,menu is full!can not add another item");
        } else {
            menuItems[num] = menuItem;
            num++;
        }
    }
}
public class DinnerMeun implements Aggregate {
    private List list;
    public DinnerMeun() {
        list = new ArrayList();
        add(new MenuItem("麻婆豆腐",18f));
        add(new MenuItem("土豆丝",12f));
        add(new MenuItem("红烧肉",30f));
    }
    public void add(MenuItem menuItem){
        list.add(menuItem);
    }
    @Override
    public Iterator createIterator() {
        return new DinnerIterator(list);
    }
}

菜单项:

public class MenuItem {
    private String name;
    private float price;
    public MenuItem(String name, float price) {
        this.name = name;
        this.price = price;
    }
    @Override
    public String toString() {
        return "MenuItem{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

招待者角色(测试主函数):

public class Waitress {
    public static void main(String[] args) {
        BreakFastMeun breakFastMeun = new BreakFastMeun();
        DinnerMeun dinnerMeun = new DinnerMeun();
        Iterator iteratorForB =  breakFastMeun.createIterator();
        Iterator iteratorForD = dinnerMeun.createIterator();
        List<Iterator> iterators = new ArrayList<Iterator>();
        iterators.add(iteratorForB);
        iterators.add(iteratorForD);
        for (int i = 0; i <iterators.size() ; i++) {
            while (iterators.get(i).hasNext()){
                System.out.println(iterators.get(i).next().toString());
            }

        }
    }
}

5.迭代器模式的优缺点:
优点:

  • 它支持以不同的方式遍历一个聚合对象
  • 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。符合JAVA的开闭原则。
    缺点:
    新增迭代器和聚合类是一对一的关系,这样设计就会导致成对增加,会导致类过多,增加系统的复杂度。
    JAVA内置的迭代器
    1.对于JAVA的众多聚合类型的数据,其本身就自带内部迭代器,例如list,使用其内部迭代器也可以遍历其中的具体内容,而不需要用for循环来操作。其内部迭代器使用方式如下,这里只做简单说明:
public class MainTest {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("123");
        list.add("456");
        list.add("789");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}
发布了62 篇原创文章 · 获赞 8 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/system_obj/article/details/86619392