设计模式-组合模式

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

  2. 特点
    组件接口同时具有叶子节点和父节点的属性,具有2种角色。组合模式以单一责任设计原则换取透明性。

  3. 代码实例

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 菜单组件,同时具有菜单和菜的角色,菜单可以有子菜单
     */
    abstract class MenuComponent {
    
        /* 菜具有的方法 */
        // 获取菜名
        public String getName() {
            throw new UnsupportedOperationException();
        }
    
        // 获取菜价格
        public int getPrice() {
            throw new UnsupportedOperationException();
        }
    
        /* 菜单具有的方法  */
    
        // 向菜单中添加菜或子菜单
        public void add(MenuComponent menuComponent) {
            throw new UnsupportedOperationException();
        }
    
        /* 共有方法 */
        public void print() {
            throw new UnsupportedOperationException();
        }
    }
    
    // 菜
    class MenuItem extends MenuComponent {
        public String name;
        public int price;
    
        public MenuItem(String name, int price) {
            this.name = name;
            this.price = price;
        }
    
        @Override
        public String getName() {
            return name;
        }
    
        @Override
        public int getPrice() {
            return price;
        }
    
        @Override
        public void print() {
            System.out.println("菜名: " + name + ": " + price);
        }
    }
    
    // 菜单
    class Menu extends MenuComponent {
        // 用于存储菜名或子菜单
        public List<MenuComponent> list = new ArrayList<>();
    
        public String menuName;
    
        public Menu(String menuName) {
            this.menuName = menuName;
        }
    
        @Override
        public void add(MenuComponent menuComponent) {
            list.add(menuComponent);
        }
    
        @Override
        public String getName() {
            return menuName;
        }
    
        @Override
        public void print() {
            System.out.println("菜单名: " + menuName);
            list.forEach(MenuComponent::print);
        }
    }
    
    // 客户端演示
    class Client {
        public MenuComponent menuComponent;
    
        public void setMenuComponent(MenuComponent menuComponent) {
            this.menuComponent = menuComponent;
        }
    
        public void print() {
            menuComponent.print();
        }
    
        public static void main(String[] args) {
            Menu menu = new Menu("主菜单");
            menu.add(new MenuItem("可乐", 3));
            menu.add(new MenuItem("炸鸡", 15));
    
            Menu subMenu = new Menu("子菜单");
            subMenu.add(new MenuItem("汉堡", 20));
            subMenu.add(new MenuItem("薯条", 10));
            // 将子菜单加入主菜单
            menu.add(subMenu);
    
            Client client = new Client();
            client.setMenuComponent(menu);
    
            // 递归打印
            client.print();
        }
    }
    
posted @ 2019-08-14 18:01  bosslv  阅读(175)  评论(0编辑  收藏  举报