迭代器模式:

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

作用:

 让我们游走于聚合内的每一个元素,而又不暴露其内部的表示。把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。

组合模式:

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

要点:
  1. 迭代器允许访问聚合的元素,而不需要暴露它的内部结构。
  2. 迭代器将遍历聚合的工作封装进一个对象中。
  3. 当使用迭代器的时候,我们依赖聚合提供遍历。
  4. 迭代器提供了一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多态机制。
  5. 我们应该努力让一个类只分配一个责任。
  6. 组合模式提供一个结构,可同时包容个别对象和组合对象。
  7. 组合模式允许客户对个别对象以及组合对象一视同仁。
  8. 组合结构内的任意对象称为组件,组件可以是组合,也可以是叶节点。
  9. 实现组合模式时,有许多设计上的折中。你要根据需要。

设计模式-迭代器模式与组合模式_组合模式

public abstract class MenuComponent {

    public void add(MenuComponent menuComponent){
        throw new UnsupportedOperationException();
    }
    public void remove(MenuComponent menuComponent){
        throw new UnsupportedOperationException();
    }
    public MenuComponent getChild(int i){
        throw new UnsupportedOperationException();
    }
    public String getName(){
        throw new UnsupportedOperationException();
    }
    public String getDescription(){
        throw new UnsupportedOperationException();
    }
    public double getPrice(){
        throw new UnsupportedOperationException();
    }
    public boolean isVegetarian(){
        throw new UnsupportedOperationException();
    }

    public void print(){
        throw new UnsupportedOperationException();
    }

    public Iterator createIterator(){
        throw new UnsupportedOperationException();
    }
}
/**
 * 菜单类
 */
public class Menu extends MenuComponent{
    ArrayList menuComponents = new ArrayList();
    String name;
    String description;

    public Menu(String name, String description) {
        this.name = name;
        this.description = description;
    }

    public void add(MenuComponent menuComponent){
        menuComponents.add(menuComponent);
    }
    public void remove(MenuComponent menuComponent){
        menuComponents.remove(menuComponent);
    }
    public MenuComponent getChild(int i){
        return (MenuComponent) menuComponents.get(i);
    }
    public String getName(){
        return name;
    }
    public String getDescription(){
        return description;
    }

    public void print(){
        System.out.println("........."+getName());
        System.out.println("........."+getDescription());
        System.out.println("-------------------------------");

        Iterator iterator = menuComponents.iterator();
        while (iterator.hasNext()){
            MenuComponent menuComponent = (MenuComponent) iterator.next();
            menuComponent.print();
        }
    }

    public Iterator createIterator(){
        return new CompositeIterator(menuComponents.iterator());
    }
}
/**
 * 菜单项
 */
public class MenuItem extends MenuComponent{

    //名称
    String name;
    //描述
    String description;
    //是否为素食
    boolean vegetarian;
    //价格
    double price;

    public MenuItem( String name, String description,boolean vegetarian,double price){
        this.name=name;
        this.description=description;
        this.vegetarian=vegetarian;
        this.price=price;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public boolean isVegetarian() {
        return vegetarian;
    }

    public double getPrice() {
        return price;
    }

    public void print(){
        System.out.println("........."+getName());
        if (isVegetarian()){
            System.out.println("(v)");
        }
        System.out.println(","+getPrice());
        System.out.println(" --"+getDescription());
    }

    public Iterator createIterator(){
        return new NullIterator();
    }
}
public class CompositeIterator implements Iterator {

    Stack stack = new Stack();


    public CompositeIterator(Iterator iterator) {
        stack.push(iterator);
    }

    public Object next(){
        if (hasNext()){//当客户取下一个的时候,先调用hasNext来确定是否还有下一个
            Iterator iterator = (Iterator) stack.peek();
            //如果有下一个元素,我们就从堆栈中去除目前的迭代器,然后取得它的下一个元素
            MenuComponent component = (MenuComponent) iterator.next();
            //如果元素是一个菜单,我们有了另一个需要被包含进遍历中的组合,所以我们将它丢进堆栈中。不管是不是菜单,我们都返回组件。
            if (component instanceof  Menu){
                stack.push(component.createIterator());
            }
            return component;
        }else {
            return null;
        }
    }

    public boolean hasNext(){
        //想要知道是否有下一个元素,我们检查栈堆是否被清空,如果已经空了,就表示没有下一个元素了。
        if(stack.empty()){
            return false;
        } else {
            Iterator iterator = (Iterator) stack.peek();
            //我们就从堆栈的顶层中取出迭代器,看看是否还有下一个元素。如果它没有元素,我们将它弹出堆栈,然后递归地调用hasNext()
            if (!iterator.hasNext()){
                stack.pop();
                return hasNext();
            }else {//表示还有下一个元素
                return true;
            }
        }
    }

    public void remove(){
        throw new UnsupportedOperationException();
    }
}
/**
 * 女招待
 */
public class Waitress {
    MenuComponent allMemus;

    public Waitress(MenuComponent allMemus) {
        this.allMemus = allMemus;
    }

    public void printMenu(){
        allMemus.print();
    }

    public void printVegetarianMenu(){
        Iterator iterator = allMemus.createIterator();
        System.out.println("\nVEGETRAIAN MENU\n-----");
        while (iterator.hasNext()){
            MenuComponent menuComponent = (MenuComponent) iterator.next();
            try {
                if (menuComponent.isVegetarian()){
                    menuComponent.print();
                }
            }catch (UnsupportedOperationException e){

            }
        }
    }
}
public class NullIterator implements Iterator {
    public Object next(){
        return null;
    }
    public boolean hasNext(){
        return false;
    }
    public void remove(){
        throw new UnsupportedOperationException();
    }
}

public class MenuTestDrive {
    public static void main(String[] args) {
        //创建所有的菜单对象
        MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU","Breakfast");
        MenuComponent denerMenu = new Menu("DINER MENU","Lunch");
        MenuComponent cafeMenu = new Menu("CAFE MENU","Dinner");
        MenuComponent dessertMenu = new Menu("DESSERT MENU","Dessert of course!");

        //创建一个顶层的菜单
        MenuComponent allMenus = new Menu("ALL MENUS","All menus combined");

        //组合方式,将每个菜单都加入到顶层菜单中
        allMenus.add(pancakeHouseMenu);
        allMenus.add(denerMenu);
        allMenus.add(cafeMenu);
        allMenus.add(dessertMenu);


        denerMenu.add(new MenuItem("素食BLT","(煎)培根、生菜&西红柿、面包",true,2.99));
        denerMenu.add(new MenuItem("BLT","培根、生菜&西红柿",false,3.99));
        denerMenu.add(new MenuItem("例汤","一碗例汤,配土豆沙拉",true,4.99));
        denerMenu.add(new MenuItem("热狗","热狗、酸菜、上盖芝士",false,5.99));
        denerMenu.add(new MenuItem("清蒸时蔬加糙米","清蒸时蔬加糙米",true,5.99));

        denerMenu.add(dessertMenu);

        dessertMenu.add(new MenuItem("Apple Pie","Apple pie with a flakey crust,topped with vanilla ice cream",true,1.59));


        pancakeHouseMenu.add(new MenuItem("K&B's薄煎饼早餐","薄煎饼、清蛋和土司",true,2.99));
        pancakeHouseMenu.add(new MenuItem("薄煎饼早餐例餐","薄煎饼带煎蛋、香肠",false,4.99));
        pancakeHouseMenu.add(new MenuItem("蓝莓薄煎饼","新鲜蓝莓和蓝莓糖浆做成的薄煎饼",true,1.99));
        pancakeHouseMenu.add(new MenuItem("松饼","松饼、可以选择蓝莓或草莓",true,3.99));

        cafeMenu.add(new MenuItem("摩卡咖啡","加糖的摩卡卡法",false,3.99));
        cafeMenu.add(new MenuItem("卡布奇洛","加奶的卡布奇洛",false,4.99));
        cafeMenu.add(new MenuItem("圣雪滴蓝","加巧克力的咖啡",false,5.23));

        Waitress waitress = new Waitress(allMenus);

        waitress.printMenu();
    }
}
设计模式-迭代器模式与组合模式_java迭代器模式_02

设计模式-迭代器模式与组合模式_迭代器模式_03

设计模式-迭代器模式与组合模式_迭代器模式_04