组合模式

组合模式(composite),将对象组合成树形结构以表示 '部分-整体' 的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

何时使用组合模式:需求中体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同(整体与部分可以一致被对待),统一地使用组合结构中的所有对象时,就应该考虑用组合模式。

透明方式与安全方式:

透明方式也就是说在Component中声明所有用来管理子对象的方法。这样实现Component接口的所有子类都具备了相同的方法。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf叶节点类本身不需要所有的方法,所以实现全部接口的方法,有些是没有意义的。

安全方式 就是Component 接口中只声明叶节点和树枝节点共同的方法,叶节点不需要的方法不声明。而是在Composite树枝节点来声明所有用来管理子类对象的方法。不过不够透明,所以叶节点和树枝节点类将不具有相同的接口,客户端的调用需要做相应的判断,这将带来不便。

组合模式的好处

基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。

组合模式让客户可以一致地使用组合结构和单个对象。(不用选择判断语句来区分叶节点和分支节点)

Component抽象类

package composite;
/**
 * 对象声明接口,声明所有类的接口
 * 透明方式
 * @author 煞笔
 *
 */
public abstract class Component {
    String name;

    public Component(String name) {
        super();
        this.name = name;
    }
    public abstract void add(Component c);
    public abstract void remove(Component c);
    public abstract void doWork();
    public abstract void display(int dept);
}

Composite类

package composite;

import java.util.ArrayList;
import java.util.List;
/**
 * 定义子节点的行为
 * @author 煞笔
 *
 */
public class Composite extends Component {
    private List<Component> list = new ArrayList<Component>();
    public Composite(String name) {
        super(name);
    }

    @Override
    public void add(Component c) {
        list.add(c);
    }

    @Override
    public void remove(Component c) {
        list.remove(c);
    }

    @Override
    public void doWork() {
        for(Component c:list){
            if(c instanceof Composite){
                System.out.println("在这里处理树枝节点的业务逻辑等"+c.name);
                c.doWork();
            }
        }
        
    }

    @Override
    public void display(int dept) {
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<dept;i++){
            sb.append(new String("-"));
        }
        System.out.println(sb.toString()+name);
        for(Component c:list){
            c.display(dept+2);
        }
    }

}

Leaf类

package composite;
/**
 * 叶节点,没有子节点
 * 方法:add/doWork/remove 没有意义,但这样做是实现透明方式,可以消除叶节点和枝节点对象在抽象层次的区别,它们具备完全一致的接口。
 * @author 煞笔
 *
 */
public class Leaf extends Component {

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

    @Override
    public void add(Component c) {

    }

    @Override
    public void remove(Component c) {

    }

    @Override
    public void doWork() {

    }

    @Override
    public void display(int dept) {
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<dept;i++){
            sb.append(new String("-"));
        }
        System.out.println(sb.toString()+name);
    }

}

Business类

package composite;

public class Business {

    public static void main(String[] args) {
        Composite root = new Composite("root");
        root.add(new Leaf("root叶节点A"));
        Composite A = new Composite("root大树主干A");
        Composite A1 = new Composite("A树枝");
        A.add(A1);
        A.add(new Leaf("A叶节点"));
        root.add(A);
        root.add(new Leaf("root叶节点B"));
        Composite B = new Composite("root大树主干B");
        Composite B1 = new Composite("B树枝");
        Composite B11 = new Composite("B1树枝");
        B11.add(new Leaf("B1叶节点"));
        B1.add(B11);
        B.add(B1);
        B.add(new Leaf("B叶节点"));
        root.add(B);
        root.add(new Leaf("root叶节点C"));
        root.display(1);
        root.doWork();
    }

}

 

posted @ 2017-07-09 17:56  永不止步!  阅读(146)  评论(0编辑  收藏  举报