美文网首页Java
设计模式之——组合模式

设计模式之——组合模式

作者: Jerry_1116 | 来源:发表于2019-03-10 22:52 被阅读0次

    1 定义

    组合模式:Composite Pattern,也叫合成模式或部分-整体模式。将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
    组合模式主要是用来描述“部分与整体”的关系。
    组合模式通用类图:


    组合模式通用类图
    • Component抽象构件角色
      定义参加组合对象的公有方法和属性,可以定义一些默认的行为或属性。一般为接口或者抽象类。
    • Leaf叶子构件
      叶子对象,下面不再有其他的分支,是遍历的最小单位。
    • Composite树枝构件
      树枝对象,作用是组合树枝节点和叶子节点来形成一个树形结构。

    2 组合模式通用代码示例

    1. 抽象构件
      抽象构件是组合模式的核心。
    @Slf4j
    public abstract class Component {
        /**
         * 个体和整体都具有的共享方法
         */
        public void operation() {
            //基础业务逻辑
            log.info("抽象构件业务逻辑。---{}", this.getClass().getSimpleName());
        }
    }
    
    1. 树枝构件
      树枝构件是组合模式的重点。
    @Slf4j
    public class Composite extends Component {
        /**
         * 构件容器
         */
        private List<Component> components = new ArrayList<>();
    
        /**
         * 增加一个叶子构件或树枝构件
         *
         * @param component 叶子构件或树枝构件
         */
        public void add(Component component) {
            this.components.add(component);
        }
    
        /**
         * 删除叶子构件或树枝构件
         *
         * @param component 叶子构件或树枝构件
         */
        public void remove(Component component) {
            this.components.remove(component);
        }
    
        /**
         * 获得分支下的所有叶子构件和树枝构件
         *
         * @return 分支下的所有叶子构件和树枝构件
         */
        public List<Component> getChilden() {
            return this.components;
        }
    }
    
    1. 叶子构件
      叶子构件没有子对象,定义了参加组合的原始对象行为。
    @Slf4j
    public class Leaf extends Component {
    
    //    /**
    //     * 可以覆写父类的方法
    //     */
    //    @Override
    //    public void operation() {
    //        super.operation();
    //    }
    
        /**
         * 叶子节点自己的业务逻辑
         */
        public void selfMethod() {
            //叶子节点自己的业务逻辑
            log.info("{}.selfMethod()", this.getClass().getSimpleName());
        }
    }
    
    1. 场景类
      场景类负责构建树状结构和遍历。
    @Slf4j
    public class Client {
        public static void main(String[] args) {
            //创建根节点
            Composite root = new Composite();
            root.operation();
            //创建一个树枝构件
            Composite branch = new Composite();
            root.add(branch);
            //创建一个叶子节点
            Leaf leaf = new Leaf();
            branch.add(leaf);
    
            //遍历树状结构
            display(root);
        }
    
        /**
         * 遍历树枝构件
         *
         * @param composite 树枝构件
         */
        private static void display(Composite composite) {
            if (Objects.isNull(composite)) {
                log.warn("composite is NULL! ");
                return;
            }
            List<Component> children = composite.getChilden();
            if (children == null || children.size() == 0) {
                log.warn("子节点为NULL或空! ");
                return;
            }
    
            for (Component component : children) {
                if (component instanceof Leaf) {
                    //叶子节点
                    component.operation();
                    ((Leaf) component).selfMethod();
                } else {
                    //树枝节点
                    display((Composite) component);
                }
            }
        }
    }
    

    3 组合模式的优缺点

    3.1 优点

    1. 高层模块调用简单
      一棵树中所有节点都是Component,局部和整体对调用者来说没有区别。高层模块不必关心自己处理的是单个对象还是整个组合结构,简化高层模块代码。
    2. 节点自由增加
      如果想增加一个树枝节点,只要找到它的父节点就可以了,非常容易扩展,符合"开闭原则"。对以后的维护非常有利。

    3.2 缺点

    不符合依赖倒置原则:在场景类中,直接使用了树叶和树枝的实现类,没有使用面向接口编程。

    4 组合模式的使用场景和注意事项

    4.1 使用场景

    1. 维护和展示"部分-整体关系"的场景
      树形结构,如属性菜单,文件/文件夹管理等场景。
    2. 从一个整体中能够独立出部分模块或功能的场景。

    参考

    1. 设计模式之禅

    相关文章

      网友评论

        本文标题:设计模式之——组合模式

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