一:基本概念
组合模式组合多个对象形成树形结构以表示“整体-部分”的结构层次。它定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程中无须进行区分,可以对他们进行一致的处理。在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。
虽然组合模式能够清晰地定义分层次的复杂对象,也使得增加新构件也更容易,但是这样就导致了系统的设计变得更加抽象,如果系统的业务规则比较复杂的话,使用组合模式就有一定的挑战了。
角色:
Component: 抽象构件
Leaf: 叶子构件
Composite: 容器构件
Client: 客户类
---------------------------------------------------------------------
组合模式相对比较简单
图一:类图
图二:文件系统
代码:
public abstract class Component {
public abstract void add(Component composite);
public abstract void remove(Component composite);
public abstract void doSomeThing();
}
public class Composite extends Component{
private List<Component> mComponents= new ArrayList<>();
@Override
public void add(Component composite) {
mComponents.add(composite);
}
@Override
public void remove(Component composite) {
mComponents.remove(composite);
}
@Override
public void doSomeThing() {
for(Component item : mComponents) {
item.doSomeThing();
}
}
}
public class Leaf extends Component{
@Override
public void add(Component composite) {
// TODO Auto-generated method stub
}
@Override
public void remove(Component composite) {
// TODO Auto-generated method stub
}
@Override
public void doSomeThing() {
// TODO Auto-generated method stub
}
}
-------------------------------------------------------------------
树状结构在软件中随处可见:操作系统的目录结构,应用软件中的菜单,办公系统中的公司组织结构等等
组合模式通过一种巧妙的设计方案使得用户可以一致性地处理树形结构中的叶子节点和容器节点。
二:分类
合成模式的实现根据所实现接口的区别分为两种形式,分别称为安全式和透明式。
安全式:
安全模式的合成模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中
举例:
/**
* 抽象构件角色类
*/
public interface Component {
/**
* 输出组件的名称
* @param preStr
*/
void printStruct(String preStr);
}
透明式:
透明式的合成模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定接口
/**
* 抽象构件角色类
*/
public abstract class Component {
/**
* 输出组件自身的名称
*/
public abstract void printStruct(String preStr);
/**
* 聚集管理方法,增加一个子构件对象
* @param child 子构件对象
*/
public void addChild(Component child){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
}
/**
* 聚集管理方法,删除一个子构件对象
* @param index 子构件对象的下标
*/
public void removeChild(int index){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
}
/**
* 聚集管理方法,返回所有子构件对象
*/
public List<Component> getChild(){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
}
}
这里所说的安全性组合模式是指:从客户端使用合成模式上看是否更安全,如果是安全的,那么就不会有发生误操作的可能,能访问的方法都是被支持的。
对于合成模式而言,在安全性和透明性上,会更看重透明性,毕竟合成模式的目的是:让客户端不再区分操作的是树枝对象还是树叶对象,而是以一个统一的方式来操作。
而且对于安全性的实现,需要区分是树枝对象还是树叶对象。有时候,需要将对象进行类型转换,却发现类型信息丢失了,只好强行转换,这种类型转换必然是不够安全的。因此在使用合成模式的时候,建议多采用透明性的实现方式
-------------------------------------------------------------------------------------------------------
三:该用哪种
透明性的使用的多一些
参考