zoukankan      html  css  js  c++  java
  • Head First 设计模式 --9 迭代器模式 组合模式

    迭代器模式:提供一种方法书序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

     用到的设计原则:
    1、封装变化
    2、多用组合,少用继承|
    3、针对接口编程,不针对实现编程
    4、松耦合
    5、对扩展开放,对修改关闭
    6、依赖抽象,不依赖具体
    7、只和朋友交谈
    8、别找我,我会找你
    9、类应该只有一个改变的理由

    迭代器模式非常简单,直接看代码(代码的意思,PancakeHouseMenu和DinerMenu两种菜单,一个用了list一个用了数组,分别对应两种类型的Iterator方便Waitress操作菜单)

    class Waitress {
      Menu pancakeHouseMenu;
      Menu dinerMenu;
    
      public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
        this.pancakeHouseMenu = pancakeHouseMenu;
        this.dinerMenu = dinerMenu;
      }
    
      public void printMenu() {
        Iterator<MenuItem> pancakeIterator = pancakeHouseMenu.createIterator();
        Iterator<MenuItem> dinerIterator = dinerMenu.createIterator();
        printMenu(pancakeIterator);
        printMenu(dinerIterator);
      }
    
      private void printMenu(Iterator<MenuItem> iterator) {
        while (iterator.hasNext()) {
          MenuItem menuItem = (MenuItem) iterator.next();
          System.out.println(menuItem.getName());
          System.out.println(menuItem.getPrice());
        }
      }
    }
    
    class MenuItem {
      String name;
      double price;
    
      public MenuItem(String name, double price) {
        this.name = name;
        this.price = price;
      }
    
      public String getName() {
        return name;
      }
    
      public double getPrice() {
        return price;
      }
    }
    
    interface Menu {
      public Iterator<MenuItem> createIterator();
    }
    
    
    class DinerMenuIterator implements Iterator<MenuItem> {
      MenuItem[] items;
      int position;
    
      public DinerMenuIterator(MenuItem[] items) {
        this.items = items;
      }
    
      @Override
      public boolean hasNext() {
        if (position >= items.length || items[position] == null) {
          return false;
        } else {
          return true;
        }
      }
    
      @Override
      public MenuItem next() {
        MenuItem menuItem = items[position];
        position = position + 1;
        return menuItem;
      }

      public void remove() {
        if (position <= 0) {
          throw new IllegalStateException();
        }
        if (items[position - 1] != null) {
          for (int i = position - 1; i < (items.length - 1); i++) {
            items[i] = items[i + 1];
          }
          items[items.length - 1] = null;
        }
      }

    
    }
    
    class DinerMenu implements Menu {
      static final int MAX_ITEMS = 6;
      int numberOfItems = 0;
      MenuItem[] menuItems;
    
      public DinerMenu() {
        menuItems = new MenuItem[MAX_ITEMS];
        addItem("diner breakfase", 1.00);
    
      }
    
      public void addItem(String name, double price) {
        MenuItem menuItem = new MenuItem(name, price);
        if (numberOfItems >= MAX_ITEMS) {
          System.out.println("menu is full");
        } else {
          menuItems[numberOfItems] = menuItem;
          numberOfItems = numberOfItems + 1;
        }
      }
    
      public Iterator<MenuItem> createIterator() {
        return new DinerMenuIterator(menuItems);
      }
    }
    
    class PancakeHouseIterator implements Iterator<MenuItem> {
      ArrayList<MenuItem> items;
      int position;
    
      public PancakeHouseIterator(ArrayList<MenuItem> items) {
        this.items = items;
      }
    
      @Override
      public boolean hasNext() {
        if (position >= items.size() || items.get(position) == null) {
          return false;
        } else {
          return true;
        }
      }
    
      @Override
      public MenuItem next() {
        MenuItem menuItem = items.get(position);
        position = position + 1;
        return menuItem;
      }

      public void remove() {
        if (position <= 0) {
          throw new IllegalStateException();
        }
        items.remove(position);
      }

    }
    
    class PancakeHouseMenu implements Menu {
      ArrayList<MenuItem> menuItems;
    
      public PancakeHouseMenu() {
        menuItems = new ArrayList<>();
        addItem("pancake house breakfase", 1.00);
    
      }
    
      public void addItem(String name, double price) {
        MenuItem menuItem = new MenuItem(name, price);
        menuItems.add(menuItem);
      }
    
      public Iterator<MenuItem> createIterator() {
        return new PancakeHouseIterator(menuItems);
      }
    }
    
    public class Test {
      public static void main(String[] args) {
        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
        DinerMenu dinerMenu = new DinerMenu();
    
        Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu);
        waitress.printMenu();
      }
    }

    类图:

    虽然代码有点多,但是还是很好理解。代码多只是因为为了用一个真实点的例子,类多了点。

     迭代器模式的类图:

    设计原则【单一权责:一个类应该只有一个引起变化的原因】

    组合模式:允许你将对向组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

    组合模式可以理解为迭代器的扩展,如果菜单中还有子菜单,那么迭代器模式就无法解决了。这是就可以考虑用组合模式。

    class TreeNode {
    
      private String name;
      private TreeNode parent;
      private Vector<TreeNode> children = new Vector<TreeNode>();
    
      public TreeNode(String name) {
        this.name = name;
      }
    
      public String getName() {
        return name;
      }
    
      public void setName(String name) {
        this.name = name;
      }
    
      public TreeNode getParent() {
        return parent;
      }
    
      public void setParent(TreeNode parent) {
        this.parent = parent;
      }
    
      // 添加孩子节点
      public void add(TreeNode node) {
        children.add(node);
      }
    
      // 删除孩子节点
      public void remove(TreeNode node) {
        children.remove(node);
      }
    
      // 取得孩子节点
      public Enumeration<TreeNode> getChildren() {
        return children.elements();
      }
    }
    
    
    class Tree {
    
      TreeNode root = null;
    
      public Tree(String name) {
        root = new TreeNode(name);
      }
    }
    
    public class CompositeTest {
      public static void main(String[] args) {
        Tree tree = new Tree("A");
        TreeNode nodeB = new TreeNode("B");
        TreeNode nodeC = new TreeNode("C");
        TreeNode nodeD = new TreeNode("D");
    
        nodeB.add(nodeC);
        nodeB.add(nodeD);
        tree.root.add(nodeB);
        tree.root.getChildren();
      }
    }

    这个模式没用书里的例子( http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html ),组合模式主要是用在树形结构中。

    一般情况下,组合模式和迭代器模式搭配使用(获取所有子节点的地方)。

  • 相关阅读:
    Linux中的文件类型
    Verilog定义变量类型为signed的几种情况
    verilog中>>>和>>的区别
    Linux中的快捷键
    Linux中的常用命令
    CVS版本控制
    [GitHub] fatal: unable to access 'https://github.com/': Failed to connect to github.com port 443: Operation timed out
    如何在手机(安卓)中搜索照片
    JS+CSS+HTML 前端开发(二)
    JS+CSS+HTML 前端开发(一)
  • 原文地址:https://www.cnblogs.com/badboyf/p/6222820.html
Copyright © 2011-2022 走看看