合成(Composite)模式
合成模式
合成(Composite)模型模式属于对象的结构模式,有时又叫部分-整体(Part-Whole)模式。合成模式将对象组织到树结构中,可以描述整体与部分的关系。合成模式可以使客户端将单纯元素与符合元素同等看待。
文件系统
一个文件系统就是一个典型的合成模式系统。下图是Mac下文件系统的一部分。
从上图可以看出文件系统是一个属性结构,树上有节点。树的节点有两种一种是树枝,一种是树叶,图中文件夹即树枝,文件即树叶。
合成模式分两种一种是安全式一种是透明式。
下图的类图省去了各角色的细节:
可以看出类图结构设计三个角色:
- 抽象构件(Component)角色:只是一个抽象角色,它给参加组合的对象规定一个接口。这个角色给出共有的接口及其默认行为。
- 树叶构件( Leaf)角色:代表参加组合的树叶对象,树叶是没有下级对象,定义参加组合的原始对象行为。
- 树枝构件(Composite)角色:代表参加组合的有子对象的对象,并给出树枝对象的行为。
可以看出,Composite类型的对象哈有其它的Component类型的对象。换言之,Composite对象包含其它所有树枝类型的对象或树叶类型的对象。
透明方式
在Component中声明所有用来管理子类对象的方法,包括:add(),remove(),以及getChild(),这样的好处是所有的构件类都有相同的接口,在客户端来看,树叶对象与合成对象的区别起码在接口层上消失了,客户端可以同等的对待所有对象,这就是透明形式的合成模式。
这种方式的缺点就是不够安全,因为树枝对象和树叶对象本质上是有区别的,树叶对象不可能有下级对象,比如add()、Remove()、以及getChild()方法没有意义,但是编译时不会出错,运行时会出错。
安全方式
安全方式是在Composite中声明所有用来管理子类的方法,这样的做法是安全做法,因为树叶类型根本没有管理子类对象的方法,因此,如果客户端对树叶类型对象使用这个方法时,程序会在编译时出错。
安全式的合成模式的结构
安全式的合成模式 要求管理聚集的方法只出现在在树枝构件类中,而不出现在树叶构件类中。如下图:
涉及三个角色,抽象构件角色,树叶构件角色,树枝构件角色,具体作用不在赘述。
代码清单1:抽象构件角色
public interface Component { Composite getComposite(); void sampleOperation(); }
代码清单2:树叶构件角色
public class Leaf implements Component { public Composite getComposite(){ // Write your code here return null; } public void sampleOperation(){ // Write your code here } }
代码清单3:树枝构件角色
import java.util.Vector; import java.util.Enumeration; public class Composite implements Component { public Composite getComposite() { return this; } public void sampleOperation() { java.util.Enumeration enumeration = components(); while (enumeration.hasMoreElements()) { ((Component)enumeration.nextElement()).sampleOperation(); } } public void add(Component component) { componentVector.addElement(component); } public void remove(Component component) { componentVector.removeElement(component); } public Enumeration components() { return componentVector.elements(); } /** * @associates <{Component}> * @link aggregation * @supplierCardinality 0..* */ private Vector componentVector = new java.util.Vector(); }
可以看出只有树枝构件给出了add()、remove()、以及component()等方法的声明和实现,而树叶构件类则没有给出这些方法的声明或实现。由于这个特点,客户端程序不可能错误的调用树叶构件的聚集方法,因为树叶构件没有这些方法,导致编译错误。
安全式的合成模式的结构
与安全式的合成模式不同的是,透明式的合成模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定接口。
代码清单1:抽象构件角色
public interface Component { void sampleOperation(); void add(Component component); void remove(Component component); Enumeration<?> components(); }
代码清单2:树枝构件角色
public class Composite implements Component { public Composite getComposite() { return this; } public void sampleOperation() { java.util.Enumeration enumeration = components(); while (enumeration.hasMoreElements()) { ((Component) enumeration.nextElement()).sampleOperation(); } } public void add(Component component) { componentVector.addElement(component); } public void remove(Component component) { componentVector.removeElement(component); } public Enumeration components() { return componentVector.elements(); } /** * @associates <{Component}> * @link aggregation * @supplierCardinality 0..* */ private Vector componentVector = new java.util.Vector(); }
代码清单3,树叶构件角色
public class Leaf implements Component { public Composite getComposite() { return null; } public void sampleOperation() { } public void add(Component component) { } public void remove(Component component) { } public Enumeration components() { return null; } /** * @associates <{Component}> * @link aggregation * @supplierCardinality 0..* */ private Vector componentVector = new java.util.Vector(); }
可以看出透明合成模式中树叶类给了add()、remove()以及components等方法的平庸实现,因为这些方法不适合用于树叶类。
下面做个安全式合成模式的例子:
/** * @author: Col.Mai * @date:2014-9-21 下午7:57:50 * @description :<p>抽象构件角色类</P> **/ public interface Component { /** * 输出组建自身的名称 */ public void printStruct(String preStr); }
import java.util.Vector; /** * @author: Col.Mai * @date:2014-9-21 下午7:58:15 * @description :<p>xxx功能描述</P> **/ public class Composite implements Component { /** * 用来存储组合对象中包含的子组件对象 */ private Vector<Component> childComponents = new Vector<Component>(); /** * 组合对象的名字 */ private String name; /** * 构造方法,传入组合对象的名字 * @param name 组合对象的名字 */ public Composite(String name){ this.name = name; } /** * 聚集管理方法,增加一个子构件对象 * @param child 子构件对象 */ public void addChild(Component child){ childComponents.add(child); } /** * 聚集管理方法,删除一个子构件对象 * @param index 子构件对象的下标 */ public void removeChild(int index){ childComponents.remove(index); } /** * 聚集管理方法,返回所有子构件对象 */ public Vector<Component> getChild(){ return childComponents; } /** * 输出对象的自身结构 * @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进 */ public void printStruct(String preStr) { // 先把自己输出 System.out.println(preStr + "+" + this.name); //如果还包含有子组件,那么就输出这些子组件对象 if(this.childComponents != null){ //添加两个空格,表示向后缩进两个空格 preStr += " "; //输出当前对象的子对象 for(Component c : childComponents){ //递归输出每个子对象 c.printStruct(preStr); } } } }
/** * @author: Col.Mai * @date:2014-9-21 下午7:59:58 * @description :<p>树叶构件角色类</P> **/ public class Leaf implements Component { /** * 叶子对象的名字 */ private String name; /** * 构造方法,传入叶子对象的名称 * @param name 叶子对象的名字 */ public Leaf(String name){ this.name = name; } /** * 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字 * @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进 */ public void printStruct(String preStr) { System.out.println(preStr + "-" + name); } }
/** * @author: Col.Mai * @date:2014-9-21 下午8:00:43 * @description : * <p> * xxx功能描述 * </P> **/ public class Client { public static void main(String[] args) { Composite root = new Composite("E"); Composite c1 = new Composite("日本浪漫爱情动作片"); Composite c2 = new Composite("美国大片"); Leaf leaf1 = new Leaf("苍井空.AVI"); Leaf leaf2 = new Leaf("小泽玛利亚.AVI"); Leaf leaf3 = new Leaf("阿凡达.mkv"); Leaf leaf4 = new Leaf("钢铁侠.mkv"); root.addChild(c1); root.addChild(c2); c1.addChild(leaf1); c1.addChild(leaf2); c2.addChild(leaf3); c2.addChild(leaf4); root.printStruct(""); } }输出如下:
+E
+日本浪漫爱情动作片
-苍井空.AVI
-小泽玛利亚.AVI
+美国大片
-阿凡达.mkv
-钢铁侠.mkv
相关推荐
在Java中实现合成模式,通常会涉及到以下关键组件: 1. **组件(Component)**:组件是所有对象的基类,无论它们是叶子节点(Leaf)还是组合节点(Composite)。组件定义了接口,这个接口用于暴露公共方法,例如添加...
### Java设计模式(刘伟) #### 一、引言 在《Java设计模式》这本书中,作者刘伟全面地介绍了24种经典的设计模式,并通过丰富的案例和代码示例进行了详细的解析。本书不仅适合初学者作为入门教材,也适合有一定...
### Java 23种设计模式详解 #### 一、设计模式概述 设计模式是指在软件设计过程中遇到的一些常见问题和解决这些问题的通用方法。通过学习和应用这些模式,程序员能够编写出更高质量、更易维护的代码。Java设计模式...
对象适配器模式是合成聚合复用原则(A) 的典型应用。它通过将一个类包装在另一个类中来实现适配,而不是通过继承来修改类的行为。 ### 14. 静态工厂的角色 静态工厂的核心角色是抽象产品(A)。静态工厂模式通过静态...
### JAVA与模式之合成模式详解 #### 一、引言 在阎宏博士的经典著作《JAVA与模式》中,合成模式被详细介绍并解释为一种重要的设计模式,它属于对象的结构模式之一,常被称为“部分—整体”模式。合成模式通过树形...
第5章 合成(composite)模式 39 第6章 桥接(bridge)模式 52 第7章 职责型模式介绍 62 第8章 单例(singleton)模式 67 第9章 观察者(observer)模式 72 第10章 调停者(mediator)模式 85 第11章 代理(proxy)模式 97 第12...
### Java设计模式经典教程知识点概览 #### 一、设计模式概述 设计模式是一种软件设计方法,它为软件开发者提供了一种标准化的方式去解决常见的软件设计问题。设计模式的使用可以提高代码的可读性和可维护性,同时...
设计模式的七大原则是软件设计中普遍存在的问题的解决方案,包括单一职责原则、接口隔离原则、依赖倒转原则、里式替换原则、开闭原则、迪米特法则和合成复用原则等。这些原则旨在让软件具有更好的复用性、扩展性、...
Java与模式:迭代子(Iterator)模式、合成(Composite)模式、抽象工厂模式等
java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元...
Java设计模式是软件开发中一种被广泛采用的方式,它是一组被反复使用、多数人知晓、分类编目、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 根据提供的文件内容,...
第5章 专题 JAVA语言的接口 第6章 专题 抽象类 第7章 里氏代换原则 第8章 依赖倒转原则 第9章 接口隔离原则 第10章 合成、聚合复用原则 第11章 迪米特法则 第12章 简单工厂模式 第13章 工厂方法模式 第14章 抽象工厂...
《Java与模式》一书由阎宏博士撰写,由电子工业出版社出版,是一部深入探讨Java编程语言与设计模式之间关系的著作。该书不仅涵盖了设计模式的基础理论,还结合了丰富的实践案例,旨在帮助读者理解和掌握如何在Java...
计算机后端-Java-图解java设计模式022 合成复用.avi
- **合成模式**:允许你将对象组合成树状结构,表示“部分-整体”的层次结构。客户端可以统一地对待单个对象和组合对象。 - **装饰器模式**:动态地给对象添加一些额外的职责,提供了比继承更多的灵活性,可以在...
Java实现多个wav文件合成一个的方法示例 本文介绍了Java实现多个wav文件合成一个的方法,涉及java文件流读写、编码转换、解析等相关操作技巧。 知识点1:Java中的文件流读写 在Java中,文件流读写是通过使用`...
Java设计模式详解合集是一份宝贵的资源,包含了丰富的面向对象设计原则和多种设计模式的深入讲解。这份资料旨在帮助开发者提升软件设计能力,遵循良好的编程实践,提高代码的可读性、可维护性和复用性。以下是其中...
Java 设计模式详解 Java 设计模式是指在软件开发过程中,为了解决一些常见的问题和难题,所采用的设计思路和方法。这些设计模式可以帮助开发者更好地组织代码,提高代码的可读性、可维护性和扩展性。 一、创建型...
合成模式允许客户端将组件和组合对象一致对待,简化了对树状结构的处理。 #### 装饰器模式(Decorator) 装饰器模式动态地给一个对象添加额外的职责,而无需修改其结构。就像在照片背后写上温馨的话语,再放入精心...