定义:组合模式也称整体-部分模式,它的宗旨是通过将单个对象(叶子节点)和组合对象(树枝节点)用相同接口进行表示。
作用:
使客户端对当个对象和组合对象保持一致的方式处理。
适用场景:
1. 希望客户端可以忽略组合对象与单个对象的差异时。
2. 对象层次具备整体和部分,如(树形结构,树形菜单,操作系统目录等)。实例代码:
/**
* 所有文件的根节点
*/
public abstract class Root {
protected String name;
public Root(String name) {
this.name = name;
}
abstract void show();
}
/**
* 文件夹
*/
public class Folder extends Root{
private Integer level;
private List<Root> child;
public Folder(String name, Integer level) {
super(name);
this.level = level;
child = new ArrayList<Root>();
}
@Override
void show() {
System.out.println(this.name);
for (Root root : this.child) {
//控制显示格式
if (this.level != null) {
for (int i = 0; i < this.level; i++) {
//打印空格控制格式
System.out.print(" ");
}
for (int i = 0; i < this.level; i++) {
//每一行开始打印一个+号
if (i == 0) {
System.out.print(" + ");
}
System.out.print("-");
}
}
//打印名称
root.show();
}
}
public boolean addChild(Root root){
return child.add(root);
}
public boolean removeChild(Root root){
return child.remove(root);
}
}
/**
* 文件
*/
public class File extends Root {
public File(String name) {
super(name);
}
@Override
void show() {
System.out.println(this.name);
}
}
public class Test {
public static void main(String[] args) {
Folder home = new Folder("home", 2);
Folder usr = new Folder("usr", 2);
home.addChild(new File("home1"));
home.addChild(new File("home2"));
home.addChild(new Folder("homeFolder1", 3));
usr.addChild(new File("usr1"));
usr.addChild(new File("usr2"));
Folder usrFolder1 = new Folder("usrFolder1", 3);
usrFolder1.addChild(new File("usrFolderChild1"));
File usrFolderChild2 = new File("usrFolderChild2");
usrFolder1.addChild(usrFolderChild2);
usrFolder1.removeChild(usrFolderChild2);
usr.addChild(usrFolder1);
Folder root = new Folder("root", 1);
root.addChild(home);
root.addChild(usr);
root.show();
}
}
结果:
root
+ -home
+ --home1
+ --home2
+ --homeFolder1
+ -usr
+ --usr1
+ --usr2
+ --usrFolder1
+ ---usrFolderChild1
类图:
上述代码展示了一个linxu文件目录结构,我们可以通过组合模式非常方便的去扩展文件,而忽略了文件层次之间的差异。
优点:
1. 清除地定义分层次的复杂对象,表示对象额全部或部分层次。
2. 让客户端忽略了层次的差异,方便对整个层次结构进行控制。
3. 简化客户端代码。
4. 符合开闭原则。
缺点:
1. 限制类型时会比较复杂。
2. 使设计变得更加抽象。