(15)组合模式



(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
    类(树枝节点类)中去具体实现了。

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

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

    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();
    }
}
时间: 2024-10-06 05:25:36

(15)组合模式的相关文章

c++设计模式15 --组合模式

今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合模式的类图一本结构 想了很久,结合源代码,才搞明白,其实这个组合,意思就是说,如果我们要做这种树状结果,比如公司想让我们吧所有部门人员的 姓名,职位,薪水遍历出来,这个时候怎么办呢?那我们看树状机构图,有叶子结点和枝干结点,2种,但是2种有共性,那就是每个结点都有姓名,职位,薪水.所有叶子结点和枝干

第 15 章 组合模式【Composite Pattern】

以下内容出自:<<24种设计模式介绍与6大设计原则>> 大家在上学的时候应该都学过“数据结构”这门课程吧,还记得其中有一节叫“二叉树”吧,我们上 学那会儿这一章节是必考内容,左子树,右子树,什么先序遍历后序遍历什么,重点就是二叉树的的遍历,我还记得当时老师就说,考试的时候一定有二叉树的构建和遍历,现在想起来还是觉的老师是正确的,树状结果在实际项目应用的非常广泛. 咱就先说个最常见的例子,公司的人事管理就是一个典型的树状结构,你想想你公司的结构是不是这样: 老大,往下一层一层的管理,

设计模式15:组合模式

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 透明方式与安全方式: 透明方式: 父类包含所有子类的方法,不需要该方法的子类可以选择throw Exception. 优点:各个子类完全一致,可以使用父类接口调用 缺点:子类实现无意义的方法 安全方式: 子类特有的方法,留到具体的子类中再去实现. 优点:子类方法有意义.

[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表

所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的 把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势 比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡 鸡腿堡+鸡翅+紫薯

组合模式(Composite)

一.组合模式介绍 组合模式:将对象组合成树形结构以表示:部分--整体 的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. java中的组合是指:在A类里定义一个B类的引用,A拥有了B,叫组合.只是单纯的组合而已,而不是一种设计模式. 组合和组合模式不是一回事! 基本上见到的树形结构都使用到了组合模式. 组合模式结构图: 组合模式中有几个核心的部分: Leaf(叶子):表示该节点下面没有其他子节点了,就称为叶子 Compostie(容器构件):容器构件,该节点下还有其他子节点,理解

设计模式 -- 组合模式(Composite)

写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------主要内容包括: 初识组合模式,包括:定义.结构.参考实现 体会组合模式,包括:场景问题.不用模式的解决方案.使用模式的解决方案 理解组合模式,包括:认识组合模式.安全性和透明性.父组件引用.环状引用.组合模式的优缺点 思考组合模式,包括:组合模式的本质.何时选用 参考内容: 1.<研磨设计模式> 一书,作者:陈臣.王斌 --

11 组合模式

组合模式(Composite)定义:将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. UML类图如下: 比如<大话>中举的例子,公司总部在北京,然后在南京.杭州设有办事处,总公司和分支办事处都有相似的组织结构,比如都有人力资源部.财务部等.如下图: 再有HeadFirst举的关于菜单的例子,如下图: 如果程序需要表达上面例子中的公司层级组织或是菜单层级的结构,就可以采用组合模式. 组合模式能让我们用树形方式创建对象的

设计模式9——组合模式

组合模式中,整体和部分可以同等看待,基类设定一个节点接口,可以派生出叶子节点和非叶子节点.叶子节点不能添加节点,非叶子节点可以添加,组成一个典型的树形结构. 组合模式在游戏引擎的渲染树中应用很广泛. Composite.h内容 1 #ifndef Composite_H_H 2 #define Composite_H_H 3 4 #include<iostream> 5 #include<vector> 6 using namespace std; 7 8 class Compos

js设计模式-组合模式

组合模式是一种专为创建web上的动态用户界面而量身定制的模式.使用这种模式,可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更容易维护,而那些复杂行为则被委托给各个对象. 组合模式实例:图片库 1 /** 2 * 图片库 3 */ 4 var Composite = new Interface("Composite",["add","remove","getChild"]); 5 var Galle