读后感觉合成模式主要用于分析需求、整理逻辑后来设计程序框架,对初学者不太合适。
概念:合成模式的意图是为了保证客户端调用单对象与组合对象的一致性。举个例子来说:对工作进程的定义,可以将其定义为进程步骤的集合以及其他进程。
举一个书中的例子:
工厂是由车间组成的,每个车间有一条或多条生产线,一条生产线上有很多机器,将这些工厂、车间、生产线看作是“机器”的组合来进行建模。
单个机器类:Machine,含有getMachineCount()方法;
生产线类:component,含有getMachineCount()方法且有多个机器对象。
车间类:MachineComposite,含有生产线列表components:List 和 getMachineCount()方法
机器接口:MachineComponent,因为机器类和车间类都有getMachineCount()这个获取机器数量的方法,所以可以抽出一个公共的接口,是他们都实现这个接口。
这样就是一个简单的合成模式了。合成模式的关键在于组合对象可以包含其他组合对象(不仅仅是叶子对象)。
再举一个网上的例子:
合成模式很多都是需要分析思考才能鉴别出来的,比如要做一个复杂的数学表达式计算器,有四种运算符号。分析发现,运算量有两种,一种是数字、一种是数字的表达式,但是表达式也是由数字组成,因此数字和表达式可以抽象为运算量。然后去表达要运算的表达式。问题迎刃而解。引自(http://lavasoft.blog.51cto.com/62575/90824)
知识点一:合成模式中的递归
如果要计算工厂中所有机器的数量,计算过程是:
得到每个叶子节点的机器数量:
Machine.getMachineCount() {
return 1;
}
在计算每个车间的:
MachineComposite.getMachineCount() {
int count = 0;
for(MachineComponent component :components) {
count += component.getMachineCount();
}
}
最后再相加得出总和;
个人理解,由于合成模式中组合和个体用到了同一个接口实现了同样的方法,而方法的功能都是相同的,所以合成模式一般都会用到递归方式。
知识点二;合成模式中的树和环
合成模式可以理解为一个树模型:有一个根,根下面会有叶节点,叶节点分为两种,一种下面还有叶节点,一种下面什么都没有了。
如果对树这个概念有理解的话,那这个模型就十分容易想象了。
个人理解,合成模式的最佳状态就是呈现为一个树模型。
但有的情况下,会出现一个子节点有两个父节点的情况,比如说一个车间有一个子节点:机器A,同时还有另一个子节点:生产线B,而B下面也对应一个子节点:机器A。
这样就会出现一个环。
个人理解,出现环的情况下最容易出现的错误就是死循环,分为两种情况:
一种是代码结构中出现的环,这种情况下就需要认真编写算法,以免出现死锁。
另一种情况是程序设计逻辑上出现的环,比如新浪微博手机端程序,会出现这种现象:由个人空间进入好友列表,再由好友列表进入他的个人空间,然后又可以进入他的好友列表,周而复始,无穷尽也。所以这种设计上的环,就需要修改项目的设计来根治了。