• 组合模式


    暂时还没遇到需要这种设计模式的情景,笔者一般会把层次结构放到数据库里,用 parentId 来标识父子关系



    1. 组合模式(Composite Pattern)

    将对象组合成树形结构以表示 “部分-整体” 的层次结构,使得用户对单个对象和组合对象的使用具有一致性



    组合模式的组成:

    • 抽象根节点(Component):存放整体的默认行为和属性

    • 树枝节点(Composite):存储叶子节点的集合

    • 叶子节点(Leaf):存放真实对象







    2. 流程

    这里很像操作系统的文件结构


    2.1 Component

    public abstract class Component {
        protected String name;
    
        public Component(String name) {
            this.name = name;
        }
    
        public abstract String hierarchical();
    
        public abstract void addChild(Component component);
    
        public abstract void removeChild(Component component);
    
        public abstract Component getChild(int index);
    }
    


    2.2 Composite

    public class Composite extends Component {
    
        private List<Component> componentList;
    
        public Composite(String name) {
            super(name);
            componentList = new ArrayList<>();
        }
    
        public String hierarchical() {
            StringBuilder builder = new StringBuilder(this.name);
            for (Component component : componentList) {
                builder.append("
    ");
                builder.append(component.hierarchical());
            }
            return builder.toString();
        }
    
        @Override
        public void addChild(Component component) {
            componentList.add(component);
        }
    
        @Override
        public void removeChild(Component component) {
            componentList.remove(component);
        }
    
        @Override
        public Component getChild(int index) {
            return componentList.get(index);
        }
    }
    


    2.3 Leaf

    public class Leaf extends Component {
        public Leaf(String name) {
            super(name);
        }
    
        @Override
        public void printAll() {
            System.out.println(this.name);
        }
    
        @Override
        public void addChild(Component component) {
            throw new UnsupportedOperationException();
        }
    
        @Override
        public void removeChild(Component component) {
            throw new UnsupportedOperationException();
        }
    
        @Override
        public Component getChild(int index) {
            throw new UnsupportedOperationException();
        }
    }
    


    2.4 案例

    public static void main(String[] args) {
    
        Component root = new Composite("root");
    
        Component branchA = new Composite("--branchA");
        Component branchB = new Composite("--branchB");
    
        Component leafA = new Leaf("----leafA");
        Component leafB = new Leaf("----leafB");
        Component leafC = new Leaf("----leafC");
    
        root.addChild(branchA);
        root.addChild(branchB);
    
        branchA.addChild(leafA);
        branchA.addChild(leafB);
        branchB.addChild(leafC);
    
        System.out.println(root.hierarchical());
    }
    
    //root
    //--branchA
    //----leafA
    //----leafB
    //--branchB
    //----leafC
    






    3. 改进

    上面的案例中叶子节点也具有根节点的方法,这是不符合逻辑的,可以使用组合模式的安全模式,即改变抽象根节点的方法,而其余不变,这样的话根和叶子的责任就明显了


    3.1 修改抽象根节点

    public abstract class Component {
        protected String name;
    
        public Component(String name) {
            this.name = name;
        }
    }
    


    3.2 文件系统

    若是文件系统,那抽象根节点还可以添加下面两个方法

    public boolean isFile() {
        return this instanceof Leaf;
    }
    
    public boolean isDir() {
        return this instanceof Composite;
    }
    


  • 相关阅读:
    phpcms 短信替换
    phpcms 搭建宣传网站首页
    JDK 8
    MySQL 5.6 date 与 string 的转换和比较
    Illustration of Git branching and merge
    Anti-pattern(反模式)
    Design Patterns笔记
    MyBatis小抄
    MyBatis MapperScannerConfigurer
    MyBatis 批量插入数据对插入记录数的限制
  • 原文地址:https://www.cnblogs.com/Howlet/p/15201857.html
Copyright © 2020-2023  润新知