组合模式

 

本文总结摘自刘伟老师的《设计模式》和程杰老师的《大话设计模式》

1.定义

组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。组合模式又可以称为“整体-部分”模式,属于对象的结构模式,它将对象组织到树结构中,可以用来描述整体与部分的关系。

2.模式动机

组合模式描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致的对待容器对象和叶子对象,这就是组合模式的模式动机。

3.模式结构

图3-1

如图3-1所示是组合模式的结构,其中Leaf为叶子构件,Composite为容器构件,Component为抽象构件。

  • Component(抽象构件):抽象构件可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。

  • Leaf(叶子构件):叶子构件在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。

  • Composite(容器构件):容器构件在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供了一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

想要理解还要看一下具体的代码:

public abstract class Component
{
	public abstract void add(Component c);
	public abstract void remove(Component c);
	public abstract Component getChild(int i);
	public abstract void operation(); 
}

一般将抽象构件类(Component)设计为接口或抽象类,将所有子类共有方法的声明和实现放到抽象构件类中。对于客户端而言,将针对抽象构件编程,而无须关心具体子类是容器构件还是叶子构件。

public class Leaf extends Component
{
	public void add(Component c)
	{ //异常处理或错误提示 }	
		
	public void remove(Component c)
	{ //异常处理或错误提示 }
	
	public Component getChild(int i)
	{ //异常处理或错误提示 }
	
	public void operation()
	{
		//实现代码
	} 
}

作为抽象构件类的子类(Leaf),在叶子构件中需要实现在抽象构件类中声明的所有方法,包括业务方法以及管理和访问子构件的方法,但是叶子构件不能再包含子构件,因此在客户端代码中调用叶子构件的子构件管理和访问方法时需要提供异常处理或错误提示。

public class Composite extends Component
{
	private ArrayList<Component> list = new ArrayList<Component>();
	
	public void add(Component c)
	{
		list.add(c);
	}
	
	public void remove(Component c)
	{
		list.remove(c);
	}
	
	public Component getChild(int i)
	{
		(Component)list.get(i);
	}
	
	public void operation()
	{
		for(Object obj:list)
		{
			((Component)obj).operation();
		}
	} 	
}

在容器构件(Composite)中实现了在抽象构件中声明的所有方法,既包括业务方法,也包括用于访问和管理子构件的方法,如add()、remove()和getChild()等方法。需要注意的是在实现具体业务方法时,由于容器构件充当的是容器角色,包含成员构件,因此它将调用其成员构件的业务方法。在组合模式的使用过程中,由于容器构件中仍旧可以包含容器构件,因此在对容器构件进行处理时需要使用递归算法,即在容器构件的operation()方法中递归调用其成员构件的operation()方法。

4.何时使用组合模式

(1)当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。

(2)让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节。

5.优缺点

优点:

  1. 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易。

  2. 客户端调用简单,客户端可以一致的使用组合结构或其中单个对象。

  3. 定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复杂的树形结构。

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

缺点:

  1. 使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。

  2. 增加新构件时可能会产生一些问题,很难对容器中的构件类型进行限制。

6.模式具体应用

  1. 由于XML文档是一个树形结构,因此可以通过组合模式对XML文档进行操作,很多XML解析工具使用组合模式对XML文档进行解析。

  2. 操作系统中的目录结构是一个树形结构,因此在对文件和文件夹进行操作时可以应用组合模式,例如杀毒软件在查毒或杀毒时,既可以针对一个具体文件,也可以针对一个目录。如果是对目录查毒或杀毒,将递归处理目录中的每一个子目录和文件。

  3. JDK的AWT/Swing是组合模式在Java类库中的一个典型实际应用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值