组合模式

2017-02-18  本文已影响0人  lgy_gg

1.组合模式概念

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

2.组合模式作用

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

3.使用场景

1、您想表示对象的部分-整体层次结构(树形结构)。
2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

4.优点和缺点

优点
1、高层模块调用简单。
2、节点自由增加。
缺点
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

5.例子解析

组合模式类图

这是一个菜单例子分为早餐,午餐,晚餐,甜点四个菜单,他们相当于节点,而Pasta(意大利面)则是晚餐的叶子,(Apple Pie)苹果派则是甜点的叶子。

对应Component:叶子和节点都继承这个类

public abstract class MenuComponent {

    public void add(MenuComponent component) {
        throw new UnsupportedOperationException();
    }
    public void remove(MenuComponent component) {
        throw new UnsupportedOperationException();
    }
    public MenuComponent getChild(int i) {
        throw new UnsupportedOperationException();
    }
    
    public String getDescription() {
        throw new UnsupportedOperationException();
    }

    public String getName() {
        throw new UnsupportedOperationException();
    }

    public double getPrice() {
        throw new UnsupportedOperationException();
    }

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

对应Composite:即节点,这里菜单就是节点

public class Menu extends MenuComponent{

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

    public String getDescription() {
        return description;
    }

    public String getName() {
        return name;
    }

    public void add(MenuComponent component) {
        menuComponents.add(component);
    }
    public void remove(MenuComponent component) {
        menuComponents.remove(component);
    }
    public MenuComponent getChild(int i) {
        return (MenuComponent) menuComponents.get(i);
    }
    
    public void print() {
        System.out.print("\n "+getName());
        System.out.println(", "+getDescription());
        System.out.println("---------------------------");
        Iterator iterator = menuComponents.iterator();
        while (iterator.hasNext()) {
            MenuComponent component = (MenuComponent) iterator.next();
            component.print();
        }
    }
}

对应Leaf:即叶子,这里的菜单子项就是叶子

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 getDescription() {
        return description;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }

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

客户端:

public class Test {

    public static void main(String[] args) {
        MenuComponent houseMenu = new Menu("PANCAKE HAUSE MENU","Breakfast");
        MenuComponent dinnerMenu = new Menu("DINNER MENU","Lunch");
        MenuComponent cafeMenu = new Menu("CAFEMENU","Dinner");
        MenuComponent dessertMenu = new Menu("DESSERT MENU","Dessert of cource");
        MenuComponent allMenu = new Menu("ALL MENU","All menus combined");
        allMenu.add(houseMenu);
        allMenu.add(dinnerMenu);
        allMenu.add(cafeMenu);
        
        dinnerMenu.add(new MenuItem("Pasta", "Spaghetti with Sauce,and a slice of sourdough bread", true, 123));
        dinnerMenu.add(dessertMenu);
        
        dessertMenu.add(new MenuItem("Apple Pie", "Apple Pie with a flakey crust, topped with vanilla ice cream", true, 321));
        
        Waitress waitress = new Waitress(allMenu);
        waitress.printMenu();
    }
}

其他:这里定义了一个服务员类,这是为了更好的还原整个订餐的流程,顾客看餐单,点餐-->服务员下单...

public class Waitress {

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

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

    private void printVegetarianMenu() {

        Iterator iterator = allMenu.createIterator();
        System.out.println("\nVEGETARIAN MENU\n------------");
        while (iterator.hasNext()) {
            MenuComponent component = (MenuComponent) iterator.next();
            try {
                if (component.isVegetarian()) {
                    component.print();
                }   
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }
}

6.总结

把组合模式当作树型结构来理解就简单了。

7.源码地址

http://download.csdn.net/detail/lgywsdy/9757732

8.参考文章

http://www.runoob.com/design-pattern/composite-pattern.html

上一篇 下一篇

猜你喜欢

热点阅读