码迷,mamicode.com
首页 > 其他好文 > 详细

(15)组合模式

时间:2015-06-19 10:35:56      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:java   设计模式   组合模式   



15)组合模式

定义:也叫合成模式,或者部分-整体模式,主要是用来描述部分与整体的关系,定义,将对象组合成树形结构以

表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

类型:结构型模式

类图:

技术分享


角色说明:

  1. Componnent抽象构件角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。

  2. Leaf叶子构件:叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。

Composite树枝构件:树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。


代码实现:

// 抽象构件类、节点类

abstract class Component {
    public String name;

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

    // 公有操作
    public void getName() {
       System.out.println(this.name);
    }

}

// 树枝构件类

class Composite extends Component {
 
    private LinkedList<Component> children;

    public Composite(String name) {
       super(name);
       this.children = new LinkedList<Component>();
    }

 
    // 添加一个节点,可能是树枝、叶子
    public void add(Component child) {
       this.children.add(child);
    }
 
    // 删除一个节点,可能是树枝、叶子
    public void remove(Component child) {
       this.children.remove(child);
    }
 
    // 获取子树
    public LinkedList<Component> getChildren() {
       return this.children;
    }
}
// 树叶构件类
class Leaf extends Component {
    public Leaf(String name) {
       super(name);
    }
}
// 测试类,负责构建整棵树

public class Client {

    public static void main(String[] args) {

       Composite root = new Composite("树根");

       Composite branch01 = new Composite("树枝01");
       Composite branch02 = new Composite("树枝02");

       root.add(branch01);
       root.add(branch02);

       Component leaf01 = new Leaf("树叶01");
       Component leaf02 = new Leaf("树叶02");
       Component leaf03 = new Leaf("树叶03");
       Component leaf04 = new Leaf("树叶04");
       Component leaf05 = new Leaf("树叶05");

       branch01.add(leaf01);
       branch01.add(leaf02);

       branch02.add(leaf03);
       branch02.add(leaf04);
       branch02.add(leaf05);
     
       displayTree(root);
    }

 

    // 递归遍历整棵树
    public static void displayTree(Composite root) {

       LinkedList<Component> children = root.getChildren();
 
       for (Component c : children) {
           if (c instanceof Leaf) {
              System.out.print("\t");
              c.getName();
           } else {
              c.getName();
              // 递归
              displayTree((Composite)c);
           }
       }
    }
}

测试结果:

树枝01
    树叶01
    树叶02
树枝02
    树叶03
    树叶04
    树叶05

优点:

  • 高层模块调用简单:一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,也就是说,高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。

  • 节点自由增加:使用了组合模式后,我们可以看看,如果想增加一个树枝节点、树叶节点是不是都很容易,只要找到它的父节点就成,非常容易扩展,符合开闭原则,对以后的维护非常有利。

    缺点:

    组合模式有一个非常明显的缺点,在场景类中的定义,树叶和树枝直接使用了实现类!这在面向接口编程上是很不恰当的,与依赖倒置原则冲突,在使用的时候要考虑清楚,它限制了你接口的影响范图。

    适用场景:

  • 维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理。

  • 从一个整体中能够强立出部分模块或功能的场景.

    组合模式的注意事项

  • 只要是树形结构,就要考虑使用组合模式,这个一定要记住,只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深, 考虑一下组合模式吧.

    组合模式的扩展:

    上面的代码中只能从根节点往下遍历,不能够从某一节点开始往上遍历,解决这个问题可以在抽象构件类 Component 类中添加一个 parent 属性,再添加相应 setParent()  getParent()方法即可。而关于不同的遍历方法再具体实现一下就完成了。上面的类图是属于安全模式的,因为 Leaf 类不具有 add remove 等方法,这些具体方法是被下置到 Composite 类(树枝节点类)中去具体实现了。

    如果要实现透明组合模式,类图如下

    技术分享

    差别仅在于将 addremove 等方法上升到抽象构件类 Component 中去了。那么此时 Leaf 类在具体实现时就必须将继承而来的 add remove 等不可用、不合逻辑的方法给注解 Deprecated 掉,并抛出适当的异常,不提供给用户使用。看起来这种透明模式似乎更加麻烦,没事找事。其实,这种模式下使得我们在遍历整棵树的时候可以不进行强制类型转换。看看上面的 displayTree() 方法,里面在使用递归遍历时就使用到了 (Compositec 强制类型转换了。

    Leaf 类代码如下:

// 树叶构件类
class Leaf extends Component {
 
    public Leaf(String name) {
       super(name);
    }

    @Deprecated // 抛出不支持的操作异常
    public void add(Component child) throws UnsupportedOperationException{
       throws new UnsupportedOperationException();
    }
 
    @Deprecated
    public void remove(String child) throws UnsupportedOperationException{
       throws new UnsupportedOperationException();
    }
 
    @Deprecated
    public LinkedList<Component> getChildren() throws UnsupportedOperationException{
       throws new UnsupportedOperationException();
    }
}

(15)组合模式

标签:java   设计模式   组合模式   

原文地址:http://blog.csdn.net/derrantcm/article/details/46556745

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!