longshu

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Composite 组合模式

  • 组合模式:
    允许你将对象组合成树形结构来表现”整体-部分”层次结构. 组合能让客户以一致的方式处理个别对象以及对象组合。
    组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性。
    组合模式又可以称为 整体—部分(Part-Whole)模式,它是一种对象结构型模式。

它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,
客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

  • 结构图:
    Composite_structure

  • 示例类图:
    Composite_uml

  • 示例代码:

// Component
public abstract class Company {
    protected String name = "";

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

    public abstract void show();
    public abstract void add(Company company);
    public abstract void remove(Company company);
}
// Composite 
public class Alphabet extends Company {
    private List<Company> children = new ArrayList<Company>();

    public Alphabet(String name) {
        super(name);
    }

    @Override
    public void show() {
        System.out.println(name);
        System.out.print("Children:");
        for (Company c : children) {
            c.show();
        }
    }

    @Override
    public void add(Company company) {
        children.add(company);
    }

    @Override
    public void remove(Company company) {
        children.remove(company);
    }
}
// Composite 
public class Google extends Company {
    private List<Company> children = new ArrayList<Company>();

    public Google(String name) {
        super(name);
    }

    @Override
    public void show() {
        System.out.println(name);
        System.out.print("\t Children : ");
        for (Company c : children) {
            System.out.print(c.name + " ");
        }
    }

    @Override
    public void add(Company company) {
        children.add(company);
    }

    @Override
    public void remove(Company company) {
        children.remove(company);
    }
}

// Leaf 
public class Android extends Company {

    public Android(String name) {
        super(name);
    }
    @Override
    public void show() {
    }
    @Override
    public void add(Company company) {
    }
    @Override
    public void remove(Company company) {
    }
}
public class YouTube extends Company {

    public YouTube(String name) {
        super(name);
    }
    @Override
    public void show() {
    }
    @Override
    public void add(Company company) {
    }
    @Override
    public void remove(Company company) {
    }
}

// 测试
public class CompositeTest {

    public static void main(String[] args) {
        Company alphabet = new Alphabet("Alphabet");
        Company google = new Google("Google");
        google.add(new Android("Android"));
        google.add(new YouTube("YouTube"));
        alphabet.add(google);

        alphabet.show();
    }
}
  • 角色:

    1. Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。
      在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
    2. Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。
      对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。
    3. Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,
      它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法.
  • 透明方式与安全方式

    1. 透明方式,也就是说在Component中声明所有用来管理子对象的方法,其中包括add,remove等。
      这样实现Component接口的所有子类都具备了add和remove。
      这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。
      但是问题也很明显,因为Leaf类本身不具备add(),remove()方法的功能,所以实现也是没意义的。
    2. 安全方式,也就是在Component接口中不去声明add和remove方法,那么字类的Leaf也不需要实现它,
      而是在Composite声明所有用来管理字类对象的方法。不过由于不透明,所以树枝类和树叶不具有相同的接口,
      客户端的调用需要做相应的判断,带来了不便。
posted on 2016-12-28 18:21  longshu  阅读(137)  评论(0编辑  收藏  举报