设计模式(十)—— 迭代器模式

一、含义

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。当我们在项目中需要遍历不同的集合、数组时,可以考虑使用迭代器模式,提供一个统一的遍历方法。

二、要点

1.迭代器将遍历聚合的工作封装进一个对象中。

2.迭代器提供一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多肽机制。

3.迭代器允许访问聚合的元素,而不需要暴露它的内部结构。

三、实战分析迭代器模式

先来看一下此设计模式的类图

例如我们在维护一个项目的时候发现,在整个项目中存放对象集合,有的地方用的是数组,有的地方用的是集合,当在一个对象中,需要遍历的时候,就显得非常麻烦,代码如下所示:

//利用数组来存放对象
public class ArrayMenu {
    static final int MAX_ITEMS = 3;
    int numberItems = 0;
    Menu[] menus;

    public ArrayMenu() {
        menus = new Menu[MAX_ITEMS];
        addItem("牛肉汉堡",22.5);
        addItem("鸡腿汉堡",15.0);
        addItem("烤鸡腿",10.0);
    }
    
    public void addItem(String name, Double price) {
        Menu menu = new Menu(name, price);
        if (numberItems > MAX_ITEMS) {
            System.out.println("数组已满,无法添加");
        } else {
            menus[numberItems] = menu;
            numberItems ++;
        }
        
    }

    public Menu[] getMenus() {
        return menus;
    }
}


//用List集合来存放对象
public class ListMenu {

    ArrayList menuItems;

    public ListMenu() {
        menuItems = new ArrayList();
        addItem("西红柿鸡蛋",12.5);
        addItem("土豆丝",10.0);
        addItem("红烧肉",30.5);

    }

    public void addItem(String name, Double price) {
        Menu menu = new Menu(name, price);
        menuItems.add(menu);
    }

    public ArrayList getMenuItems() {
        return menuItems;
    }
}

当我需要在一个类里需要同时遍历时,代码就很显得很重复

public class ListArrayTest {
    ListMenu listMenu = new ListMenu();
    ArrayMenu arrayMenu = new ArrayMenu();

    ArrayList menuItems = listMenu.getMenuItems();
    Menu[] menus = arrayMenu.getMenus();
    
    
    public void getMenu() {
        for (int i = 0; i < menuItems.size(); i++) {
            Menu menu = (Menu) menuItems.get(i);
            System.out.println(menu.getName() + " ");
            System.out.println(menu.getPrice() + " ");
            
        }

        for (int i = 0; i < menus.length; i++) {
            Menu menu = menus[i];
            System.out.println(menu.getName() + "");
            System.out.println(menu.getPrice() + "");
        }
    }
}

这个时候我们的迭代器模式就要闪亮登场了,首先我们定义一个迭代器接口:

//定义一个迭代器接口
public interface Iterator {
    
    //判断是否有更多的元素
    boolean hasNext();
    
    //返回下一个元素
    Object next();
    
}

然后实现一个具体的迭代器方法:

public class MenuIterator implements Iterator {
    
    Menu[] menus;
    int position = 0;

    public MenuIterator(Menu[] menus) {
        this.menus = menus;
    }

    @Override
    public boolean hasNext() {
        if (position >= menus.length || menus[position] == null) {
            return false;
        } else {
            return true;
        } 
        
    }

    @Override
    public Object next() {
        Menu menu = menus[position];
        position ++;
        return menu;
    }
}

然后我们就可以改造我们之间的代码了:

 //加入一个创建构造器的方法即可
 public Iterator createIterator() {
        return new MenuIterator(menus);
 }

这个时候在编写我们的测试类:

public class ListArrayTest {
    ListMenu listMenu = new ListMenu();
    ArrayMenu arrayMenu = new ArrayMenu();

    
    public void getIterator() {
        Iterator MenuIterator = arrayMenu.createIterator();
        Iterator ListIterator = listMenu.createIterator();
    }
    
    
    private void printMenu(Iterator iterator) {
        while (iterator.hasNext()) {
            Menu menu = (Menu) iterator.next();
            System.out.println(menu.getName() + " ");
            System.out.println(menu.getPrice() + " ");
        }
        
    }
}

代码看上去就简洁了许多,测试结果:

西红柿鸡蛋 
12.5 
土豆丝 
10.0 
红烧肉 
30.5 
牛肉汉堡
22.5
鸡腿汉堡
15.0
烤鸡腿
10.0

文章内容参考《Head First 设计模式》

猜你喜欢

转载自blog.csdn.net/huxiaodong1994/article/details/84701257