国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php框架 > 框架设计 > 设计模式(九)组合模式(Composite)-结构型

设计模式(九)组合模式(Composite)-结构型

来源:程序员人生   发布时间:2015-05-12 09:23:50 阅读次数:4097次

组合模式Composite

组合模式也叫合成模式,又叫树形模式,就是把部份和整体的关系用树形结构来表示,是的客户端对单个对象和组合对象的使用具有1致性,可以看出,这里的部份和整体之间在功能上是类似的,对这类类似性,通常可以采取继承的方式来实现,根据面向对象的设计原则,尽可能使用组合而非继承,因此合成模式也是继承的1个替换方案。

1.组合模式结构

这里写图片描述
组合模式实现原理图

组合模式就是把部份和整体的关系用树形结构来表示,从而是客户端能够把1个1个的部份对象和他们组合起来的整体对象采取一样的方式来看待。它也是继承的1个替换方案,使用组合模式,能够提供比使用继承关系更灵活的功能,并且可以灵活地组合子对象和父对象之间的关系,从而是客户真个调用简单,客户端可以1致的使用组合结构或单个对象,用户没必要关心自己处理的是单个对象还是全部组合结构,这简化了客户端代码

2. 构建模式的组成

组合模式主要3个部份:抽象类叶子类父类
抽象构件角色(component):这是1个抽象角色,它给参加组合的定义出公共的接口和默许的行动。可以来管理所有的子对象。在安全式的合成模式里面,构件角色其实不是定义管理子对象的方法,这1定义由树形构件对象给出。
树叶构件角色(Leaf):在组合树中表示叶节点对象,叶节点没有子节点。并在组合中定义图元对象的行动。
树枝构件角色(Composite):定义有子部件的那些部件的行动。存储子部件。在Component接口中实现与子部件有关的操作。
客户角色(Client):通过component接口操纵组合部件的对象。

3. 组合模式功效

(1) 定义了包括基本对象和组合对象的类层次结构 基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去。客户代码中,任何用到 基本对象的地方都可使用组合对象。
(2)简化客户代码 客户可以1致地使用组合结构和单个对象。通经常使用户不知道 (也不关心)处理的是1个叶节点还是1个组合组件。这就简化了客户代码 , 由于在定义组合的那些类中不需要写1些充斥着选择语句的函数。
(3)使得更容易增加新类型的组件 新定义的Composite或Leaf子类自动地与已有的结构和客户代码1起工作,客户程序不需因新的Component类而改变。
(4)使你的设计变得更加1般化 容易增加新组件也会产生1些问题,那就是很难限制组合中的组件。有时你希望1个组合只能有某些特定的组件。使用Composite时,你不能依赖类型系统施加这些束缚,而必须在运行时刻进行检查。

4.实现代码

举例:生活中常常用到的加减乘除运算,有时还要对基本运算后的数据再次运算,下面使用组合模式实现。
SalaryComputer.java

package com.devin.composite; /** * @author 作者:ldw E-mail: csu.ldw@csu.edu.cn * @version 创建时间:2015年4月25日 上午9:16:12 * 类说明 */ public interface SalaryComputer { public double computer(double m,double n); }

加法运算类代码:
Add.java

package com.devin.composite; /** * @author 作者:ldw E-mail: csu.ldw@csu.edu.cn * @version 创建时间:2015年4月25日 上午9:16:47 * 类说明 */ public class Add implements SalaryComputer{ @Override public double computer(double m, double n) { return m+n; } }

减法类实现代码:
Subtract.java

package com.devin.composite; /** * @author 作者:ldw E-mail: csu.ldw@csu.edu.cn * @version 创建时间:2015年4月25日 上午9:16:47 * 类说明 */ public class Subtract implements SalaryComputer{ @Override public double computer(double m, double n) { return m-n; } }

乘法类实现代码:
Multiplication.java

package com.devin.composite; /** * @author 作者:ldw E-mail: csu.ldw@csu.edu.cn * @version 创建时间:2015年4月25日 上午9:16:47 * 类说明 */ public class Multiplication implements SalaryComputer{ @Override public double computer(double m, double n) { return m*n; } }

除法类实现代码:
Division.java

package com.devin.composite; /** * @author 作者:ldw E-mail: csu.ldw@csu.edu.cn * @version 创建时间:2015年4月25日 上午9:16:47 * 类说明 */ public class Division implements SalaryComputer{ @Override public double computer(double m, double n) { return m/n; } }

组合类运算代码
Composite.java

package com.devin.composite; import java.util.ArrayList; import java.util.List; /** * @author 作者:ldw E-mail: csu.ldw@csu.edu.cn * @version 创建时间:2015年4月25日 上午9:18:20 * 类说明 */ public class Composite implements SalaryComputer { private List<SalaryComputer> list = new ArrayList<SalaryComputer>(); public void add(SalaryComputer salaryComputer){ list.add(salaryComputer); } public void remove(SalaryComputer salaryComputer){ list.remove(salaryComputer); } @Override public double computer(double m, double n) { double count = 0; for (int i = 0; i < list.size(); i++) { SalaryComputer salaryComputer = (SalaryComputer)list.get(i); count+= salaryComputer.computer(m, n); } System.out.println("m=" + m + ",n="+ n +" 计算后的结果为"+count); return count; } }

客户端代码:
Client.java

package com.devin.composite; /** * @author 作者:ldw E-mail: csu.ldw@csu.edu.cn * @version 创建时间:2015年4月25日 上午9:23:46 * 类说明 */ public class Client { public static void main(String[] args) { Composite salaryComputer = new Composite(); salaryComputer.add(new Division()); salaryComputer.computer(2000, 5); } }

5. 测试结果

m=1000.0,n=5.0 计算后的结果为200.0

6. 组合模式和其他相干模式

(1)装潢模式(Decorator模式)常常与Composite模式1起使用。当装潢和组合1起使用时,它们通常有1个公共的父类。因此装潢必须支持具有 Add、Remove和GetChild 操作的Component接口。
(2)享元模式(Flyweight)模式让你同享组件,但不再能援用他们的父部件。
(3)迭代器模式(Itertor)可用来遍历Composite。
(4)视察者模式(Visitor)将本来应当散布在Composite和L e a f类中的操作和行动局部化。

7. 总结

  • 组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素1样来处理复杂元素。
  • 如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那末组合模式就是最理想的选择.

实际中的利用

JUnit单元测试框架等。

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生