模式定义:
组合模式组合多个对象形成树形结构以表示“整体-部分”的结构层次。
在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。
模式结构:
模式实现:
public class CompositeMode {
/**
* 测试类
*/
@Test
public void compositeTest() {
Folder folder1 = new Folder("Folder 1");
Folder folder2 = new Folder("Folder 2");
Folder folder3 = new Folder("Folder 3");
FileImg fileImg1 = new FileImg("file 1", "ah");
FileImg fileImg2 = new FileImg("file 2", "hehe");
FileImg fileImg3 = new FileImg("file 3", "haha");
folder1.addChild(folder2);
folder1.addChild(fileImg1);
folder2.addChild(fileImg2);
folder2.addChild(folder3);
folder3.addChild(fileImg3);
System.out.println(folder1.getName(0));
}
/**
* 组件,提供统一方法
*/
abstract class Component {
public void addChild(Component component) {
throw new UnsupportedOperationException();
}
public void removeChild(Component component) {
throw new UnsupportedOperationException();
}
public Component getChild(int i) {
throw new UnsupportedOperationException();
}
/**
* 之所以加int参数,是为了递归打印好看。(- 。-)
*
* @param i
* @return
*/
public String getName(int i) {
throw new UnsupportedOperationException();
}
public String getDescription() {
throw new UnsupportedOperationException();
}
}
/**
* 文件夹
*/
class Folder extends Component {
String name;
List<Component> components;
public Folder(String name) {
this.name = name;
components = new ArrayList<>();
}
@Override
public void addChild(Component component) {
components.add(component);
}
@Override
public void removeChild(Component component) {
components.remove(component);
}
@Override
public Component getChild(int i) {
return components.get(i);
}
@Override
public String getName(int i) {
StringBuilder sb = new StringBuilder(name);
sb.append("\n");
for (Component component : components) {
for (int j = 0; j < i; j++) {
sb.append("\t");
}
sb.append("\t").append(component.getName(i + 1));
}
return sb.toString();
}
}
class FileImg extends Component {
String name;
String description;
public FileImg(String name, String description) {
this.name = name;
this.description = description;
}
@Override
public String getName(int i) {
return name + "\n";
}
@Override
public String getDescription() {
return description;
}
}
}
模式优点:
1、可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易
2、客户端调用简单,客户端可以一致的使用组合结构或其中单个对象
3、定义了包含叶子对象和容器对象的类层次结构,可不断递归下去,可以形成复杂的树形结构
4、更容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有代码
模式缺点:
1、使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联
适用场景:
1、需要表示一个对象整体或部分层次,在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,可以一致地对待它们
2、让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节
3、树
注意点:
1、可以在抽象组件中跑出异常,用来区别非法操作,也可重写所有方法,合理设计实现及返回值
2、如果添加时需要排序,则,,,,数据结构,红黑树(呵呵)
3、子节点太多,遍历麻烦,可增加缓存