组合模式概念
以下摘自菜鸟教程
意图:将对象组合成树形结构以表示”部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
何时使用:
1、您想表示对象的部分-整体层次结构(树形结构)。
2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。
应用实例:
1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作符也可以是操作数、操作符和另一个操作数。
2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。优点:
1、高层模块调用简单。
2、节点自由增加。缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。
注意事项:定义时为具体类。
组合模式主要突出两个关键字:树形结构、整体-部分
接下来先看一个案例
案例
已知,电脑中文件与文件夹。父文件夹中可以存在子文件和子文件夹,子文件夹中又可以存在其子文件夹的子文件和子文件夹。
Component(抽象构件)
可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
public interface Component {
/**
* 添加组件
* @return void
* @param component
* 时间:2018年4月27日
*/
void add(Component component);
/**
* 移除组件
* @return void
* @param component
* 时间:2018年4月27日
*/
void remove(Component component);
/**
* 获取组件
* @return Component
* @param i
* @return
* 时间:2018年4月27日
*/
Component getCom(int i);
/**
* 需要执行的方法
* @return void
* 时间:2018年4月27日
*/
void operation();
}
Leaf(叶子构件)
在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。
public class CFile implements Component{
private String name;
public CFile(String name) {
this.name = name;
}
@Override
public void add(Component component) {
System.out.println("error");
}
@Override
public void remove(Component component) {
System.out.println("error");
}
@Override
public Component getCom(int i) {
System.out.println("error");
return null;
}
@Override
public void operation() {
System.out.println(name);
}
}
Composite(容器构件)
在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。
public class CFolder implements Component{
private String name;
private List<Component> list;
public CFolder(String name) {
this.name = name;
list = new ArrayList<>();
}
@Override
public void add(Component component) {
list.add(component);
}
@Override
public void remove(Component component) {
list.remove(component);
}
@Override
public Component getCom(int i) {
return list.get(i);
}
@Override
public void operation() {
System.out.println(name);
System.out.println("打开了:" + name);
for (Component component : list) {
component.operation();
}
}
}
测试类
public class Test {
public static void main(String[] args) {
Component component1 = new CFile("A");
Component component2 = new CFile("B");
Component component3 = new CFile("C");
Component component4 = new CFile("D");
Component component5 = new CFolder("1");
Component component6 = new CFolder("2");
Component component7 = new CFolder("3");
component5.add(component1);
component5.add(component2);
component5.add(component6);
component6.add(component3);
component6.add(component7);
component7.add(component4);
component5.operation();
}
}
本文参考