设计模式之组合模式

来源:互联网 发布:手机淘宝怎么改地址 编辑:程序博客网 时间:2024/05/29 23:22

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


Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。

通常都用add和remove方法来提供增加或移除树叶或树枝的功能。

public abstract class Component {    protected String mName;    public Component(String name) {        mName = name;    }    public abstract void add(Component component);    public abstract void remove(Component component);    public abstract void display(int depth);}

Leaf在组合中表示叶节点对象,叶节点没有子节点。由于叶节点没有再增加分枝和树叶,所以add和remove方法实现它没有意义,但这样做可以消除叶节点和枝节点对象在抽象层次的区别,它们具备完全一致的接口。

public class Leaf extends Component {    public Leaf(String name) {        super(name);    }    @Override    public void add(Component component) {    }    @Override    public void remove(Component component) {    }    @Override    public void display(int depth) {        System.out.println("-" + depth + mName);    }}

Composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加add和删除remove。

public class Composite extends Component {    // 一个子对象集合,用来存储其下属的枝节点和叶节点    private List<Component> mChildren = new ArrayList<Component>();    public Composite(String name) {        super(name);    }    @Override    public void add(Component component) {        mChildren.add(component);    }    @Override    public void remove(Component component) {        mChildren.remove(component);    }    @Override    public void display(int depth) {        // 显示其枝节点名称,并对其下级进行遍历        System.out.println("-" + depth + mName);        for (Component item : mChildren) {            item.display(depth + 1);        }    }}

调用:

Composite root = new Composite("root");root.add(new Leaf("Leaf A"));root.add(new Leaf("Leaf B"));Composite comp = new Composite("Composite X");comp.add(new Leaf("Leaf XA"));comp.add(new Leaf("Leaf XB"));root.add(comp);root.add(new Leaf("Leaf C"));Leaf leaf = new Leaf("Leaf D");root.add(leaf);root.remove(leaf);root.display(1);

输出结果:

-1root-2Leaf A-2Leaf B-2Composite X-3Leaf XA-3Leaf XB-2Leaf C

透明方式与安全方式:

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

安全方式,也就是在Component接口中不去声明add和remove方法,那么子类的Leaf也就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法,不过由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。

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

组合模式定义了包含基本对象和组合对象的层次结构。基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。

用户是不用关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而写一些选择判断语句了。

组合模式让客户可以一致地使用组合结构和单个对象。

Android中view和viewGroup就是用组合模式实现的。

0 0
原创粉丝点击