`
Col.Man
  • 浏览: 18323 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java合成模式

阅读更多

合成(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

  • 大小: 12.6 KB
  • 大小: 7.7 KB
  • 大小: 22.8 KB
  • 大小: 28.8 KB
分享到:
评论

相关推荐

    设计模式之合成模式Java实现和类设计图

    设计模式之合成模式的Java实现版本,包括UML类设计图,包含了两种实现,安全式和透明式

    JAVA与模式

     合成模式属于对象的结构模式,有时又叫做“部分——整体”模式。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。 合成模式  合成模式把部分...

    [Java设计模式(第2版)(Design.Patterns.in.Java).John.Metsker

    第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 设计模式

    java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元...

    Java与模式(清晰书签版) 设计模式 part3

    第5章 专题 JAVA语言的接口 第6章 专题 抽象类 第7章 里氏代换原则 第8章 依赖倒转原则 第9章 接口隔离原则 第10章 合成、聚合复用原则 第11章 迪米特法则 第12章 简单工厂模式 第13章 工厂方法模式 第14章 抽象工厂...

    计算机后端-Java-图解java设计模式022 合成复用.avi

    计算机后端-Java-图解java设计模式022 合成复用.avi

    Java与模式.清晰.rar

    Java与模式.清晰.rar 第一部分 第1章 模式的简史和形而上学 第2章 统一建模语言UML简介 第二部分 第3章 软件的可维护性与可复用性 第4章 “开-闭”原则 第5章 专题:Java语言的接口 第6章 专题:抽象类 第7章 里氏...

    java 设计模式与Jar库

    java 设计模式与Jar库 里氏代换原则LSP 依赖倒转原则DIP 接口隔离原则ISP 合成/聚合复用原则CARP

    java和设计模式ppt教程

    java和设计模式ppt包含工厂模式、建造模式、原始模型模式、单例模式、结构模式、适配器、桥梁模式、合成模式、装饰模式、门面模式、享元模式、代理模式、行为模式、解释器模式、迭代子模式、调停者模式、备忘录模式...

    java与模式

    1:模式的简史和形而上学;2:统一建模语言UML简介;3:软件的可维护性与可复用性;4:开-闭 原则;5:java语言接口;6:抽象类;...24:合成模式;25:装饰模式;26:设计模式在JAVA I/O设计原则;28:代理模式;....

    java_模式part2.rar

    Java语言的接口 抽象类 里氏代换原则 依赖倒转原则 接口隔离原则 合成/聚合复用原则 迪米特法则 简单的工厂 工厂的方法 抽象工程 单例(singleton) 原始模型 适配器 装饰 代理 门面模式 不变模式 策略模式 模板方法

    java_模式.part1.rar

    Java语言的接口 抽象类 里氏代换原则 依赖倒转原则 接口隔离原则 合成/聚合复用原则 迪米特法则 简单的工厂 工厂的方法 抽象工程 单例(singleton) 原始模型 适配器 装饰 代理 门面模式 不变模式 策略模式 模板方法

    JAVA常用设计模式

    分类 创建模式 工厂模式;建造模式;原始模型模式;单例模式 结构模式 适配器;桥梁模式;合成模式;装饰模式;门面模式;享元模式;代理模式 行为模式 优点 面向界面编程 降低耦合性 增加灵活性

    《Java设计模式(第2版)》

    3、行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 二、设计模式遵循的原则有6个: 1、开闭原则...

    2023年 java面试题.docx

    Java设计模式的类别有哪些? 基于问题分析,可以将设计模式分为以下几类: 创造模式 工厂方法/模板模式 抽象工厂模式 建造者模式 原型模式 ...合成模式 装饰者模式 正面模式 蝇量级模式 代理模式 行为模式

    JAVA_API1.6文档(中文)

    javax.xml.bind.annotation 定义将 Java 程序元素定制成 XML 模式映射的注释。 javax.xml.bind.annotation.adapters XmlAdapter 及其规范定义的子类允许任意 Java 类与 JAXB 一起使用。 javax.xml.bind.attachment...

    尚硅谷设计模式源码笔记课件.zip

    1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种...

    图解Java设计模式(一)

    单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,...

    Java模式.part3.rar

    Java语言的接口 抽象类 里氏代换原则 依赖倒转原则 接口隔离原则 合成/聚合复用原则 迪米特法则 简单的工厂 工厂的方法 抽象工程 单例(singleton) 原始模型 适配器 装饰 代理 门面模式 不变模式 策略模式 模板方法

Global site tag (gtag.js) - Google Analytics