美文网首页
组合模式

组合模式

作者: lgy_gg | 来源:发表于2017-02-18 22:16 被阅读0次

    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

    相关文章

      网友评论

          本文标题:组合模式

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