设计模式-结构型-组合模式

定义

组合模式,又叫部分-整体模式,合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。

这里是引用阎宏博士的《JAVA与模式》

windows的文件系统就是最常见的组合模式,如下图
设计模式-结构型-组合模式_第1张图片
从上图可以看出,文件系统是一个树结构,树上有节点。树的节点有两种,一种是树枝节点,即目录,有内部树结构,另一种是叶子节点,和在学校学过的二叉树结构很像。
组合模式应用或者作用
组合模式可以把目录和文件当做同一种对象同等对待和处理。
特点
组合模式可以不提供父对象的管理方法,但是合成模式必须在合适的地方提供子对象的管理方法,诸如:add()、remove()、以及getChild()等。
组合模式的种类2种
组合模式的实现根据所实现接口的区别分为两种形式,分别称为安全式透明式
a安全式组合模式的结构
设计模式-结构型-组合模式_第2张图片
这种形式涉及到三个角色:

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

抽象构件

  // 组件
public interface component {
    void operation();
}

树叶构件

public class Leaf implements component {
    String name;
    // 树叶实现了组件
    @Override
    public void operation() {
        System.out.println(name);
    }

    public Leaf(String name) {
        this.name = name;
    }
}

树干构件

  // 树枝或者叫树干实现了组件
public class Composite implements component {
    String name;
    //用来存储组合对象中包含的子组件对象
    List list = new ArrayList();

    public Composite(String name) {
        this.name = name;
    }
    public  void add(component c){
        list.add(c);
    }
    public void remove(int index){
        list.remove(index);
    }
    @Override
    public void operation() {
        System.out.println(name);
        list.forEach(e->e.operation());
    }

客户端调用

// 客户端调用
public class Client {
    public static void main(String[] args) {
    Composite composite = new Composite("总部");
    component company1 = new Leaf("上海分公司");
    component company2 = new Leaf("南京分公司");
    composite.add(company1);
    composite.add(company2);
    composite.operation();
    }
}

运行结果

总部
上海分公司
南京分公司

Process finished with exit code 0

b透明式组合模式的结构
设计模式-结构型-组合模式_第3张图片
抽象构件
// 组件

public abstract class component {
    public abstract void operation();
    public abstract void add(component c);
    public abstract void remove(int index);
}

叶子构件

public class Leaf extends component {
    String name;
    // 树叶实现了组件
    @Override
    public void operation() {
        System.out.println(name);
    }

    @Override
    public void add(component c) {

    }

    @Override
    public void remove(int index) {

    }

    public Leaf(String name) {
        this.name = name;
    }
}


树干构件

// 树干实现了组件
    public class Composite extends component {
        String name;
        List list = new ArrayList();
    
        public Composite(String name) {
            this.name = name;
        }
        public  void add(component c){
            list.add(c);
        }
        public void remove(int index){
            list.remove(index);
        }
        @Override
        public void operation() {
            System.out.println(name);
            list.forEach(e->e.operation());
        }
    }

客户端

public class Client {
    public static void main(String[] args) {
    component composite = new Composite("总部");
    component company1 = new Leaf("上海分公司");
    component company2 = new Leaf("南京分公司");
    composite.add(company1);
    composite.add(company2);
    composite.operation();
    }
运行结果和安全式组合模式一致

总部
上海分公司
南京分公司

Process finished with exit code 0

两种实现方法的选择
安全性组合模式安全是指:不会有发生误操作的可能,能访问的方法都是被支持的。

透明性组合模式透明是指:从客户端使用组合模式上,是否需要区分到底是“树枝对象”还是“树叶对象”。如果是透明的,那就不用区分,对于客户而言,都是Compoent对象,具体的类型对于客户端而言是透明的,是无须关心的。
  
透明性组合模式在实际应用中使用的更多一些,因为安全性组合模式有时候需要面临判断是树叶构件还是树枝构件的类型判断,可能会涉及到强制类型转换,必然是不够安全的。

你可能感兴趣的:(设计模式)