合成模式

2015/10/25
  1. 抽象构件(component)角色:这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。合成对象通常把它所包含的子对象当成类型为component的对象。在安全式的合成模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝构件对象给出。
  2. 树叶构件(leaf)角色:树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。
  3. 树枝构件(composite)角色:代表参加组合的有下级子对象的对象。树枝构件类给出所有的管理子对象的方法,如add(),remove()以及getChild()

    // 抽象构件角色类
    public interface Component {
        /**
         * 输出组建自身的名称
         */
        public void printStruct(String preStr);
    }
    
    // 树枝构件角色类
    public class Composite implements Component {
        /**
         * 用来存储组合对象中包含的子组件对象
         */
        private List<Component> childComponents = new ArrayList<Component>();
        /**
         * 组合对象的名字
         */
        private String name;
        /**
         * 构造方法,传入组合对象的名字
         * @param name    组合对象的名字
         */
        public Composite(String name){
            this.name = name;
        }
        /**
         * 聚集管理方法,增加一个子构件对象
         * @param child 子构件对象
         */
        public void addChild(Component child){
            childComponents.add(child);
        }
        /**
         * 聚集管理方法,删除一个子构件对象
         * @param index 子构件对象的下标
         */
        public void removeChild(int index){
            childComponents.remove(index);
        }
        /**
         * 聚集管理方法,返回所有子构件对象
         */
        public List<Component> getChild(){
            return childComponents;
        }
        /**
         * 输出对象的自身结构
         * @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进
         */
        @Override
        public void printStruct(String preStr) {
            // 先把自己输出
            System.out.println(preStr + "+" + this.name);
            //如果还包含有子组件,那么就输出这些子组件对象
            if(this.childComponents != null){
                //添加两个空格,表示向后缩进两个空格
                preStr += "  ";
                //输出当前对象的子对象
                for(Component c : childComponents){
                    //递归输出每个子对象
                    c.printStruct(preStr);
                }
            }
    
        }
    
    }
    
    // 树叶构件角色类
    public class Leaf implements Component {
        /**
         * 叶子对象的名字
         */
        private String name;
        /**
         * 构造方法,传入叶子对象的名称
         * @param name 叶子对象的名字
         */
        public Leaf(String name){
            this.name = name;
        }
        /**
         * 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
         * @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
         */
        @Override
        public void printStruct(String preStr) {
            // TODO Auto-generated method stub
            System.out.println(preStr + "-" + name);
        }
    
    }
    
    // 客户端类
    public class Client {
        public static void main(String[]args){
            Composite root = new Composite("服装");
            Composite c1 = new Composite("男装");
            Composite c2 = new Composite("女装");
    
            Leaf leaf1 = new Leaf("衬衫");
            Leaf leaf2 = new Leaf("夹克");
            Leaf leaf3 = new Leaf("裙子");
            Leaf leaf4 = new Leaf("套装");
    
            root.addChild(c1);
            root.addChild(c2);
            c1.addChild(leaf1);
            c1.addChild(leaf2);
            c2.addChild(leaf3);
            c2.addChild(leaf4);
    
            root.printStruct("");
        }
    }