一、简介
1.1 模式定义
组合多个对象形成树形结构一表示“整体-部分”的结构层次。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性。
1.2 使用场景
1)需要表示一个对象整体或部分层次,在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,可以一致地对待他们。
2)让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节。
3)对象的结构是动态的并且复杂程度不一样,但客户需要一致地处理它们。
1.3 优点
1)组合模式可以清楚地定义层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易,因为它让客户忽略了层次的差异,而它的结构又是动态的,提供来临对象管理的灵活接口,因此组合模式可以方便地对层次结构进行控制。
2)客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不关心自己处理的是单个对象和容器对象的类层次结构,简化了客户端代码。
3)定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复杂的树形结构。
4)更容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有代码。
1.4 缺点
1)使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。
2)增加新构件时可能产生一些问题,很难对容器中的构件类型进行限制。有时候我们希望一个容器中只能有某些特定类型的对象,使用组合模式时,不能依赖类型系统来施加这些约束,因为他们都来自于相同的抽象层,在这种情况下,必须要通过在运行时进行类型检查来实现,这个实现过程较为复杂。
二、示例
2.1 结构图
2.2 抽象构建类MyElement
public abstract class MyElement {
public abstract void eat();
}
2.3 叶子构建类Apple
public class Apple extends MyElement{
@Override
public void eat() {
System.out.println("吃苹果!");
}
}
2.4 叶子构建类Banana
public class Banana extends MyElement{
@Override
public void eat() {
System.out.println("吃香蕉!");
}
}
2.5 容器构建类Plate(水果盘)
public class Plate extends MyElement{
List<MyElement> list = new ArrayList<>();
public void add(MyElement element) {
list.add(element);
}
public void remove(MyElement element) {
list.remove(element);
}
@Override
public void eat() {
for(MyElement element : list) {
element.eat();
}
}
}
来源:CSDN
作者:书香水墨
链接:https://blog.csdn.net/qq_27870421/article/details/103657558