设计模式之11--组合模式

来源:互联网 发布:新浪用户数据库价格 编辑:程序博客网 时间:2024/06/05 13:29

组合模式学习笔记

软件产品设计过程会遇到诸如遍历文件夹和文件的情况(这只是一种情况,还有部分和员工),而在文件夹里面可能还会存在文件夹和文件,那么如果要统一对文件夹和文件进行某些操作(比如杀毒)那么我们该怎么进行呢?这里就需要使用组合模式来进行设计。

组合模式为处理树形结构提供了一种较为完美的解决方案,它描述了如何将容器和叶子进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器和叶子。(在上面的例子中,文件夹就是容器而文件就是叶子)。

组合模式:组合多个对象形成树形结构以表示具有“整体-部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为”整体-部分”模式,它是一种对象结构型模式

个人认为,组合模式中将容器类和叶子类共同的方法行为都抽象出来,形成一个抽象的父类,而叶子类对于行为进行真正的实现,而在容器类里面,该方法会进行递归的调用,最后仍然会调用到叶子类的方法,客户端类只需要和抽象类打交道就好,无须关系整个系统区分的叶子和容器

下图是组合模式的结构图:

从上面可以看出组合模式一共含有三种角色:

Component抽象构件,通过将容器和叶子共有的方法抽象出来形成抽象构件类,该类里面声明了子类所有的行为接口。

Leaf叶子构件:叶子构件类里面实现了抽象构件中定义的行为,它不能包含其他叶子。

Composite容器构件:作为抽象构件的子类,它同样也是含有所有的行为接口的,而对于它含有的子容器或者叶子,统一都是递归的调用业务方法。

抽象构件既可以代表叶子,也可以代表容器,客户端就可以通过抽象容器直接处理。

实现代码:

abstract class Component {    public abstract void operation();    public abstract void add(Component  c);    public abstract void remove(Component c);}class Leaf extends Component {    public void operation(){        /*TODO*/    }    //当然这里还有add remove等方法的实现}class Composite extends Component {    private ArrayList<Component> list = new ArrayList<Component>();    public void operation(){        for(Object obj:list) {            ((Component)obj).operation();        }    }    //同样这里也有add和remove方法实现}那么在客户端调用的时候:class Client {    public static void main(String args[]) {        Component file1 = new Leaf();        Component file2 = new Leaf();        Component file3 = new Leaf();        Component folder1 = new Composite();        folder1.add(file2);        folder1.add(file3);        folder1.operation();    }}

从上面客户端使用的代码可以看出客户类对叶子和容器是不可见的,统一通过Component抽象构件类进行编程,而对于容器类的操作,而依次遍历list里面的成员,如果某个成员又是子容器类的话,那么就会递归的再进行子容器类的operation操作。

对于上面的代码中,抽象构件声明的add和remove方法大家可能会有疑惑,因为在叶子类中是不应该有这两个接口的实现的,毕竟叶子再也不能包含叶子或者容器了。那如果所有的方法都声明在抽象构件中,那么叶子结点里面实现的时候就需要对这两个方法进行出错提醒,而在容器类中则没问题。对于这个问题有两种解决方法。

第一种,我们可以把诸如叶子类不支持的方法移除抽象构件,让它仅仅包含叶子和容器共同有的行为,这样子的话叶子就无须支持add和remove,而容器类中我们可以单独增加add和remove方法,但是这样子一来客户类使用的时候就不能统一使用抽象构件类来声明容器类(因为容器类中很多方法Component不支持),否则的话就会导致容器类新增的接口对于客户类不可见。这属于安全组合模式。

第二种,是将所有的行为都在Component类中进行默认定义,那么在Leaf类中无须处理,容器类中重写这些方法行为就好,但是因为在客户类看来,这种方式中的叶子结点和容器结点行为方法都是相同的,因此还是属于透明组合模式。

总结:
组合模式可以很清楚地分清楚层次对象,对于系统中的组合对象和单个对象,组合模式是统一对待的,简化了客户端的代码。组合模式使得在具有整体和部分的层次结构中的设计忽略掉整体和部分的差异,统一对待。

0 0
原创粉丝点击