`

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

阅读更多

Composite模式定义:

    将对象以树形结构组织起来,以达成部分-整体的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。

    Composite比较容易理解,想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。

Composite好处:

    1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关心自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。

    2.更容易在组合体内加入对象部件,客户端不必因为加入了新的对象部件而更改代码。

如何使用Composite?

    首先定义一个接口或抽象类,这是设计模式通用方式了,其他设计模式对接口内部定义限制不多,Composite却有个规定,那就是要在接口内部定义一个用于访问和管理Composite组合体的对象们(或称部件Component)。

    Composite模式要对组合的对象进行管理,所以在一定位置给予对象的相关管理方法,如:add(),remove().Composite模式中对象的管理有两种方案。

    1.安全方式:此方式只允许树枝构件有对象的管理方法。

    2.透明方式:此方式只允许树枝和树叶都有对象的管理方法,但树叶对象中的管理方法无实际意义。

一.UML示意图


    
 二.组成部分

    抽象构件:抽象组合对象的公共行为接口

    树叶构件:树叶对象,没有下级子对象

    树枝构件:树枝对象,树枝对象可以包含一个或多个其他树枝或树叶对象

三.代码例子

1.抽象构件

 

package com.composite;

public interface IFile {
	/**
	 * 返回自己的实例
	 * @return
	 */
	public IFile getComposite();
	
	/**
	 * 获取名字
	 * @return
	 */
	public String getName();
	
	/**
	 * 设置名字
	 * @param name
	 */
	public void setName(String name);
	
	/**
	 * 获取深度
	 * @return
	 */
	public int getDeep();
	/**
	 * 设置深度
	 * @param deep
	 */
	public void setDeep(int deep);
}

 2.叶子构件

 

package com.composite;


public class File implements IFile{

	/**
	 * 文件名字
	 */
	private String name;
	/**
	 * 层级深度,根为0
	 */
	private int deep;
	
	public File(String name) {
		this.name = name;
	}
	
	@Override
	public IFile getComposite() {
		return this;
	}
	
	@Override
	public String getName() {
		return name;
	}

	@Override
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public int getDeep() {
		return deep;
	}

	@Override
	public void setDeep(int deep) {
		this.deep = deep;
	}

}

  3.树枝构件

 

package com.composite;

import java.util.Vector;

public class Folder implements IFile{

	/**
	 * 文件名字
	 */
	private String name;
	/**
	 * 层级深度,根为0
	 */
	private int deep;
	
	/**
	 * 直接子文件(夹)集合
	 */
	private Vector<IFile> component = new Vector<IFile>();
	
	public Folder(String name) {
		this.name = name;
	}
	
	@Override
	public IFile getComposite() {
		return this;
	}
	
	/**
	 * 新增一个文件或文件夹
	 * @param file
	 */
	public void add(IFile file)
	{
		component.addElement(file);
		file.setDeep(this.deep+1);
	}
	
	/**
	 * 删除一个文件或文件夹
	 * @param file
	 */
	public void remove(IFile file)
	{
		component.removeElement(file);
	}
	
	/**
	 * 获取直接子文件(夹)集合
	 * @return
	 */
	public Vector<IFile> getComponent()
	{
		return this.component;
	}
	
	@Override
	public String getName() {
		return name;
	}

	@Override
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public int getDeep() {
		return deep;
	}

	@Override
	public void setDeep(int deep) {
		this.deep = deep;
	}

}

 4.测试

 

package com.composite;

import java.util.Iterator;
import java.util.Vector;

public class Test {
	public static void main(String[] args) {
		Folder root = new Folder("根节点");
		
		Folder folder1_1 = new Folder("1_分支1");
		
		Folder folder1_2 = new Folder("1_分支2");
		
		File f1_1 = new File("1_叶1");
		
		File f1_2 = new File("1_叶2");
		
		File f1_3 = new File("1_叶3");
		
		Folder folder2_1 = new Folder("2_分支1");
		
		Folder folder2_2 = new Folder("2_分支2");
		
		File f2_1 = new File("2_叶1");
		
		File f2_2 = new File("2_叶2");
		
		root.add(folder1_1);
		root.add(folder1_2);
		root.add(f1_1);
		root.add(f1_2);
		root.add(f1_3);
		
		folder1_2.add(folder2_1);
		folder1_2.add(folder2_2);
		folder1_2.add(f2_1);
		
		folder2_2.add(f2_2);
		
		outTree(root);
	}
	
	public static void outTree(Folder folder)
	{
		System.out.println(folder.getName());
		iterateTree(folder);
	}
	
	public static void iterateTree(Folder folder)
	{
		Vector<IFile> clist = folder.getComponent();
		for(Iterator<IFile> it = clist.iterator();it.hasNext();)
		{
			IFile em = it.next();
			if(em instanceof Folder)
			{
				Folder cm = (Folder) em;
				System.out.println(getIndents(em.getDeep())+cm.getName());
				iterateTree(cm);
			}else
			{
				System.out.println(getIndents(em.getDeep())+((File)em).getName());
			}
		}
	}
	
	public static String getIndents(int x)
	{
		StringBuffer sb = new StringBuffer();
		for(int i=0;i<x;i++)
		{
			sb.append("\t");
		}
		return sb.toString();
	}
}

 5.结果


    

四.总结

    组合模式是对象的结构模式。在以后的项目中,如果遇到对象组合的情况,即也符合树结构的。可以考虑下此模式。此模式中讲述了安全方式和透明方式。
    安全方式:抽象构件上只提供树叶和树枝公共的方法,没提供树枝独有的管理等方法(add(),remove())。这样的好处是安全,用户不会在树叶上使用add()等管理方法,缺点是不够透明,用户必须知识当前对象为树叶还是树枝(向下转型)。

    透明方式:抽象构件上提供了满足树枝的所有方法(包括add(),remove()),这样做的好处是,用户可以任意执行对象的add()remove()管理对象。缺点是如果用户在树叶上执行管理方式(add(),remove())时,在编译期不会有错,但在执行期会报错,这样不容易被发觉错误出在哪

  • 大小: 4.2 KB
  • 大小: 752 Bytes
分享到:
评论

相关推荐

    设计模式-Java语言中的应用(pdf)

    《设计模式——Java语言中的应用》是一本专为Java开发者深入理解面向对象设计而编写的经典书籍。设计模式是软件工程领域中经过实践验证的、解决常见问题的有效方案,它们代表了在特定上下文中,针对特定问题的最优...

    JAVA设计模式学习10——组合模式

    组合模式是一种结构型设计模式,它允许我们使用树形结构来表示部分-整体关系,使得我们能够像处理单个对象一样处理整个集合。在JAVA中,组合模式的应用可以帮助开发者更灵活地处理对象间的层次结构,使得客户端代码...

    设计模式——JAVA.docx

    ### JAVA设计模式总结之23种设计模式及六大原则 #### 一、设计模式之六大原则 ##### 总原则:开闭原则(Open Close Principle) 开闭原则是设计模式中最核心的原则之一,它强调的是软件实体(类、模块、函数等)...

    设计模式可复用面向对象软件的基础.zip

    2.2.3 组合模式 27 2.3 格式化 27 2.3.1 封装格式化算法 27 2.3.2 Compositor和Composition 27 2.3.3 策略模式 29 2.4 修饰用户界面 29 2.4.1 透明围栏 29 2.4.2 Monoglyph 30 2.4.3 Decorator 模式 32 2.5 支持多种...

    设计模式C++实现(7)——外观模式、组合模式[参照].pdf

    设计模式 C++ 实现(7)——外观模式、组合模式 本文主要介绍了设计模式中的外观模式和组合模式,并使用 C++ 实现了两个模式的示例代码。外观模式提供了一个高层接口,封装了子系统中的复杂结构,使得客户使用起来...

    23种 设计模式---面向对象的基本原则

    - 组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。 - 装饰模式(Decorator):动态地给一个对象添加一些额外的职责,提供比继承更...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    C++设计模式课件20_Composite_组合模式.pdf

    本篇主要探讨的是结构型模式之一——组合模式。 #### 二、组合模式定义 组合模式(Composite Pattern)是一种树形结构的设计模式,它将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户可以对...

    设计模式精解——GoF23中设计模式解析

    ### 设计模式精解——GoF23中设计模式解析 #### 重要性与起源 设计模式是软件工程领域的一项重要研究,它提供了一系列解决常见软件设计问题的模板。GoF23指的是由Erich Gamma、Richard Helm、Ralph Johnson和John ...

    设计模式代码——c#

    9. 组合模式(Composite Pattern) 10. 外观模式(Facade Pattern) 11. 享元模式(Flyweight Pattern) 12. 代理模式(Proxy Pattern) 行为型 13. 模板方法(Template Method) 14. 命令模式(Command Pattern) ...

    设计模式实验报告-组合模式.docx

    ### 设计模式实验报告——组合模式 #### 实验目的与背景 本次实验旨在通过实践学习设计模式中的组合模式,理解其工作原理及应用场景。组合模式(Composite Pattern)是一种结构型设计模式,它允许用户将对象组合成...

    设计模式精解-GoF 23种设计模式解析附C++.pdf

    ### 设计模式精解——GoF 23种设计模式解析及C++实现 #### 0. 引言 设计模式作为面向对象编程的核心组成部分,是软件开发者在长期实践中总结出来的最佳实践。通过深入理解这些设计模式,我们可以更好地进行面向...

    Python设计模式之组合模式原理与用法实例分析

    本文实例讲述了Python设计模式之组合模式原理与用法。...设计模式——组合模式 组合模式(Composite Pattern):将对象组合成成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用

    设计模式PPT---25种设计模式详解

    3. 组合模式(Composite):允许你将对象组合成树形结构来表现“整体/部分”层次结构。 4. 装饰模式(Decorator):动态地给对象添加新的职责。 5. 外观模式(Facade):为子系统提供一个统一的接口,简化了客户端...

    X-gen PPT下载——《研磨设计模式》 实战

    2. **结构型模式**:如适配器模式(Adapter)、装饰器模式(Decorator)、代理模式(Proxy)、桥接模式(Bridge)、组合模式(Composite)、外观模式(Facade)和享元模式(Flyweight)。这些模式处理对象之间的关系...

    设计模式C++版(pdf版)

    ### 设计模式精解——GoF 23种设计模式解析及C++实现源码 #### 引言 设计模式是软件工程领域中一个极为重要的概念,它代表着一系列被广泛接受的解决特定问题的方法。GoF(Gang of Four)所提出的23种设计模式更是...

    设计模式精解-GoF 23种设计模式解析附C++实现源码.pdf

    - **2.4 Composite模式**:组合模式允许你将对象组合成树形结构来表示部分整体的层次结构。 - **2.5 Flyweight模式**:享元模式用于减少大量相似对象的内存消耗。 - **2.6 Facade模式**:外观模式为子系统中的一组...

Global site tag (gtag.js) - Google Analytics