美文网首页
迭代器模式

迭代器模式

作者: 狐尼克朱迪 | 来源:发表于2016-10-22 16:03 被阅读0次

    定义

    提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

    使用场景

    • 访问聚合对象的内容,而不会暴露其内部表示
    • 支持聚合对象的多遍遍历
    • 提供用于穿过不同聚集体结构的均匀界面

    例子

    举一个遍历百宝箱的例子:
    首先定义箱中宝贝的类型

    // 元素类型 任何一个、武器、指环、药水
    public enum ItemType {
      ANY, WEAPON, RING, POTION
    }
    

    定义一下宝贝对象,包括类型和名字两个字段:

    // 元素对象
    public class Item {
      private ItemType type;
      private String name;
    
      public Item(ItemType type, String name) {
        this.setType(type);
        this.name = name;
      }
      public ItemType getType() {
        return type;
      }
      public final void setType(ItemType type) {
        this.type = type;
      }
    }
    

    定义下百宝箱:

    // 百宝箱
    public class TreasureChest {
      private List<Item> items;
    
      public TreasureChest() {
        items = new ArrayList<>();
        items.add(new Item(ItemType.POTION, "Potion of courage"));
        items.add(new Item(ItemType.RING, "Ring of shadows"));
        items.add(new Item(ItemType.POTION, "Potion of wisdom"));
        items.add(new Item(ItemType.POTION, "Potion of blood"));
        items.add(new Item(ItemType.WEAPON, "Sword of silver +1"));
        items.add(new Item(ItemType.POTION, "Potion of rust"));
        items.add(new Item(ItemType.POTION, "Potion of healing"));
        items.add(new Item(ItemType.RING, "Ring of armor"));
        items.add(new Item(ItemType.WEAPON, "Steel halberd"));
        items.add(new Item(ItemType.WEAPON, "Dagger of poison"));
      }
    
      ItemIterator iterator(ItemType itemType) {
        return new TreasureChestItemIterator(this, itemType);
      }
    
      public List<Item> getItems() {
        List<Item> list = new ArrayList<>();
        list.addAll(items);
        return list;
      }
    }
    

    定义迭代器接口和实现迭代器:

    // 迭代器接口
    public interface ItemIterator {
      boolean hasNext();
      Item next();
    }
    
    // 百宝箱迭代器
    public class TreasureChestItemIterator implements ItemIterator {
      private TreasureChest chest;
      private int idx;
      private ItemType type;
    
      public TreasureChestItemIterator(TreasureChest chest, ItemType type) {
        this.chest = chest;
        this.type = type;
        this.idx = -1;
      }
    
      public boolean hasNext() {
        return findNextIdx() != -1;
      }
    
      public Item next() {
        idx = findNextIdx();
        if (idx != -1) {
          return chest.getItems().get(idx);
        }
        return null;
      }
    
      private int findNextIdx() {
        List<Item> items = chest.getItems();
        boolean found = false;
        int tempIdx = idx;
        while (!found) {
          tempIdx++;
          if (tempIdx >= items.size()) {
            tempIdx = -1;
            break;
          }
          if (type.equals(ItemType.ANY) || items.get(tempIdx).getType().equals(type)) {
            break;
          }
        }
        return tempIdx;
      }
    }
    

    遍历下百宝箱:

    // 测试
    public class App {
      public static void main(String[] args) {
        TreasureChest chest = new TreasureChest();
    
        ItemIterator ringIterator = chest.iterator(ItemType.RING);
        while (ringIterator.hasNext()) {
          System.out.println(ringIterator.next());
        }
    
        ItemIterator it = chest.iterator(ItemType.ANY);
        while (it.hasNext()) {
          System.out.println(it.next());
        }   
      }
    }
    

    分析

    迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露其内部表示。把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。
    迭代器模式很好的体现了:一个类应该只有一个引起变化的原因这个设计原则。类的每个责任都有改变的潜在区域。超过一个责任,意味着超过一个改变的区域。 这个原则告诉我们,尽量让每个类保持单一责任。

    参考

    iluwatar/java-design-patterns

    相关文章

      网友评论

          本文标题:迭代器模式

          本文链接:https://www.haomeiwen.com/subject/mbkhuttx.html