组合设计模式(部分-整体设计模式)
主要角色涉及三个
抽象构件角色(component):规定参加参加组合的对象共有的行为,这个接口可以用来管理所有的子对象。
树叶构件角色:参加对象组合的树叶对象。给出add(),remove()之类的方法的平庸实现。一般针对树叶构件的角色不提供add(),remove()等管理子对象的方法。
树枝构件角色:参加组合的对象含有子对象的对象。
组合模式以树结构图的形式去理解。树枝节点可以添加和管理子类元素。树叶节点不具备添加和管理子组件的能力。
所以又分透明式和安全式。
透明式
下面以我的电脑中的文件夹为例,文件可以增加文件。文件不能再添加子文件。已经是树叶节点。
树叶和树枝都实现文件夹接口,文件夹可以添加子类文件。同时也继续添加子类文件夹。
而文件是树叶不具备添加子类文件的能力。故提供一个平庸实现。
//抽象构件类
public interface Folder{
//访问文件夹
public void visit(Folder folder);
//添加
public void add(Folder foler);
//删除
public void revmove(Folder folder);
//多少个文件
public int size();
}
//文件
public class FileLeaf implements Folder{
//访问文件
public void visit(Folder folder){
System.out.println("访问当前的文件")
}
//平庸实现
public void add(Folder folder){
}
//平庸实现
public void remove(Folder folder){
}
public int size(){
}
}
import java.util.List;
import java.util.ArrayList;
public class CompositeFolder implements Folder{
//管理集合的属性
private List<Folder> componentList = new ArrayList<Folder>();
//访问当前的文件夹
public void visit(Folder folder){
if(!CollectionUtils.isEmpty()){
for(Folder der:componentList){
if(der==folder){
System.out.println("访问当前的树枝节点")
}
}
}
}
//添加
public void add(Folder folder){
componentList .add(folder);
}
public void remove(Folder folder){
componentList .remove(folder);
}
public int size(){
componentList.size();
}
}
透明式的缺点是运行时。由于树叶节点不具备添加或者删除子文件的能力。运行时会报错。
安全式组合模式
//抽象构件类
public interface Folder{
//访问文件夹
public void visit(Folder folder);
}
//文件是树叶节点,不具备添加子类文件的能力。不提供这类操作
public class FileLeaf implements Folder{
//访问文件
public void visit(Folder folder){
System.out.println("访问当前的文件")
}
}
//树枝节点提供一个统一的访问接口。有管理子类的能力
public interface CompositeFolder extends Component{
//添加
public void add(Folder foler);
//删除
public void revmove(Folder folder);
//多少个文件
public int size();
}
//树枝节点实现类 实现抽树枝接口类
public class CompositeFolderImpl implements CompositeFolder{
private List<Folder> compositeList = new ArrayList<Folder>();
//添加
public void add(Folder folder){
compositeList.add(folder);
}
//删除
public void remove(Folder folder){
compositeList.remove(folder);
}
//多少个文件
public int size(){
compositeList.size();
}
//访问当前的文件夹
public void visit(Folder folder){
if(!CollectionUtils.isEmpty()){
for(Folder der:componentList){
if(der==folder){
System.out.println("访问当前的树枝节点")
}
}
}
}
}
应用场景:
1, 你表示部分/整体层次结构
2,不用区分单个构件和组合构件的区别时。
优点:
1,客户端很容易添加新的构件,树枝节点和树叶节点。
2,使客户端设计更容易。因为对树枝和树叶节点都是同等对待。
缺点:
1,通过继承的方式添加新的行为很苦难。
2,控制树枝构件的类型不太容易。