设计模式学习笔记--合成(Composite)模式


写在模式学习之前


       什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式;每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案;当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。

       设计模式就是抽象出来的东西,它不是学出来的,是用出来的;或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以“模式专家”的角度来看,都是最佳的设计,不得不说是“最佳的模式实践”,这是因为你积累了很多的实践经验,知道“在什么场合代码应该怎么写”,这本身就是设计模式。

       有人说:“水平没到,学也白学,水平到了,无师自通”。诚然,模式背熟,依然可能写不出好代码,更别说设计出好框架;OOP理解及实践经验到达一定水平,同时也意味着总结了很多好的设计经验,但"无师自通",却也未必尽然,或者可以说,恰恰是在水平和经验的基础上,到了该系统的学习一下“模式”的时候了,学习一下专家总结的结果,印证一下自己的不足,对于提高水平还是很有帮助的。

       本系列的设计模式学习笔记,实际是对于《Java与模式》这本书的学习记录。


合成(Composite)定义


 合成(Composite)模式,有时又叫做部分-整体(Part-Whole)模式。合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。合成模式可以使客户端将单纯元素与复合元素同等看待。

结构图:


合成模式的实现根据所实现接口的区别分为两种形式,分别称为安全式和透明式。合成模式可以不提供父对象的管理方法,但是合成模式必须在合适的地方提供子对象的管理方法。在什么地方声明子对象的管理办法,可以选择的有如下两种:

透明方式:在 Compoment 声明所有方法,好处是所有构件接口相同,缺点是不够安全,因为叶子节点和树枝节点是有区别的,叶子节点不能有下一个层次对象。

安全方式:在 Composite 声明所有方法,因此如果在编译期对于叶子节点使用这些方法,编译就会报错,比较安全,缺点是不够透明,因为叶子节点和树枝节点将具有不同的接口。


安全式的合成模式


结构图

所涉及的角色

(1)抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。合成对象通常把它所包含的子对象当做类型为 Component 的对象。在安全式的合成模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝构件对象给出。

(2)树叶构件(Leaf)角色:树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。

(3)树枝构件(Composite)角色:代表参加组合的有下级子对象的对象。树枝构件类给出所有的管理子对象的方法,如add()、remove()以及components()的声明。

代码实现

import java.util.*;
interface Component
{
	//返还自己的实例
	Composite getComposite();
	//某个商业方法
	void sampleOp();
}
class Composite implements Component
{
	private List<Component> componentList = new ArrayList<Component>();
	//返还自己的实例
	public Composite getComposite()
	{
		return this;
	}
	//某个商业方法
	public void sampleOp()
	{
		Iterator it = componentList.iterator();
		while(it.hasNext())
		{
			((Component)it.next()).sampleOp();
		}
	}
	//容器管理,增加子构件对象
	public void add(Component c)
	{
		componentList.add(c);
	}
	//容器管理,删除子构件对象
	public void remove(Component c)
	{
		componentList.remove(c);
	}
}
class Leaf implements Component
{
	//返还自己的实例
	public Composite getComposite()
	{
		//Write you code here
		return null;
	}
	//某个商业方法
	public void sampleOp()
	{
		//Write your code here
	}
}

透明式的合成模式


结构图


所涉及的角色

(1)抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象规定一个接口,规范共有的接口及默认行为。这个接口可以用来管理所有的子对象,要提供一个接口以规范取得和管理下层组件的接口,包括add()、remove()以及getChild()之类的方法。

(2)树叶构件(Leaf)角色:代表参加组合的树叶对象,定义出参加组合的原始对象的行为。树叶类会给出add()、remove()以及getChild()之类的用来管理子类对象的方法的平庸实现。

(3)树枝构件(Composite)角色:代表参加组合的有子对象的对象,定义出这样的行为。

代码实现

import java.util.*;
interface Component
{
	//返还自己的实例
	Composite getComposite();
	//某个商业方法
	void sampleOp();
	//容器管理,增加子构件对象
	void add(Component c);
	//容器管理,删除子构件对象
	void remove(Component c);
}
class Composite implements Component
{
	private List<Component> componentList = new ArrayList<Component>();
	//返还自己的实例
	public Composite getComposite()
	{
		return this;
	}
	//某个商业方法
	public void sampleOp()
	{
		Iterator it = componentList.iterator();
		while(it.hasNext())
		{
			((Component)it.next()).sampleOp();
		}
	}
	//容器管理,增加子构件对象
	public void add(Component c)
	{
		componentList.add(c);
	}
	//容器管理,删除子构件对象
	public void remove(Component c)
	{
		componentList.remove(c);
	}
}
class Leaf implements Component
{
	//返还自己的实例
	public Composite getComposite()
	{
		//Write you code here
		return null;
	}
	//某个商业方法
	public void sampleOp()
	{
		//Write your code here
	}
	//容器管理,增加子构件对象
	public void add(Component c)
	{
	}
	//容器管理,删除子构件对象
	public void remove(Component c)
	{
	}
}

更多了解


(1)在JDK中对于合成模式使用最多的地方,当属AWT库,java.awt.Button/java.awt.CheckBox等是树叶构件,java.awt.Container是树枝构件,java.awt.Component是抽象构件。

(2)在下面的情况下应当考虑使用合成模式:a、需要描述对象的部分和整体的等级结构;b、需要客户端忽略掉个体构件和组合构件的区别;客户端必须平等对待所有的构件,包括个体构件和组合构件。

(3)实际生产中,对于分类、权限、部门之类具有树形层级关系的结构,非常适合应用合成模式;比如树形分类,以前可能只建立一个和数据表行完全一致的model类,现在可以根据合成模式的思想发展一下,使其完成更多的职责,更容易使用。这个扩展也不必一定要有树叶构件、抽象构件,可能只有树枝构件,总之,适合具体场景即可。

(4)个人在学习过程中,从找不到合成模式的场景,到理解到可以对以前设计的优化,发展开阔了很多,似乎有点“顿悟”的感觉大笑


结构模式(Structural Pattern)小结


结构模式(Structural Pattern)一共有七种,分别是:适配器模式、装饰模式、合成模式、代理模式、享元模式、门面模式、桥梁模式。

大致总结如下:

 最大特点典型应用
适配器模式利用对象的功能,并转换其接口日常工作,入目尽是适配器,DAO适配,Cache功能适配,等等
装饰模式对象层面的功能增强,接口不变Java I/O类库的设计
合成模式树枝、叶子同样对待分类树、权限树等
代理模式代表人WebService 的本地代理,权限访问代理,引用计数代理等
享元模式共享对象,减小内存占用编译器系统,Java String
门面模式统一对外接口,方便调用基于SOA框架编程中,不同系统之间的接口
桥梁模式解耦大多数的驱动器,包括JDBC Driver

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值