组合模式通过一种巧妙的设计方案,使得用户可以一致性地处理整个树形结构或者树形结构的一部分,它描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无需对它们进行区分,可以一致地对待容器对象和叶子对象,这就是组合模式的模式动机。
定义如下:
组合模式:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式可让客户端可以统一对待单个对象和组合对象。
组合模式包含3个角色:
1,Component(抽象构件):它为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有的声明和实现。
2,Leaf(叶子构件):叶子结点没有子结点。
3,Composite(容器构件):容器结点包含子结点,其子结点可以是叶子结点,也可以是容器结点。它提供了一个集合用于存储子结点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子结点的业务方法。
案例代码示例。
//对于抽象构件角色
/**
* 抽象构件类
*/
public abstract class AbstractControl {
public abstract void add(AbstractControl control);
public abstract void remote(AbstractControl control);
public abstract AbstractControl getChild(int i);
public abstract void show();
}
//叶子构件角色
/**
* 充当叶子构件类
*/
public class ButtonControl extends AbstractControl{
private String name;
public ButtonControl(String name) {
this.name = name;
}
@Override
public void add(AbstractControl control) {
System.out.println("对不起,不支持该方法");
}
@Override
public void remote(AbstractControl control) {
System.out.println("对不起,不支持该方法");
}
@Override
public AbstractControl getChild(int i) {
System.out.println("对不起,不支持该方法");
return null;
}
@Override
public void show() {
System.out.println("【"+this.name+"】模拟Button控件内容或业务方法");
}
}
/**
* 充当叶子构件类
*/
public class TextControl extends AbstractControl{
private String name;
public TextControl(String name) {
this.name = name;
}
@Override
public void add(AbstractControl control) {
System.out.println("对不起,不支持该方法");
}
@Override
public void remote(AbstractControl control) {
System.out.println("对不起,不支持该方法");
}
@Override
public AbstractControl getChild(int i) {
System.out.println("对不起,不支持该方法");
return null;
}
@Override
public void show() {
System.out.println("【"+this.name+"】模拟Text控件内容或业务方法");
}
}
//容器构件角色
/**
* 充当容器构件类
*/
public class Window extends AbstractControl {
private List controlList = new ArrayList<>();
private String name;
public Window(String name) {
this.name = name;
}
@Override
public void add(AbstractControl control) {
controlList.add(control);
}
@Override
public void remote(AbstractControl control) {
control.remote(control);
}
@Override
public AbstractControl getChild(int i) {
return controlList.get(i);
}
@Override
public void show() {
//比如要展示子类的所有内容或调用子类的所有业务方法,需要递归调用成员构件的方法
for (AbstractControl control : controlList) {
control.show();
}
}
}
/**
* 充当容器构件类
*/
public class Panel extends AbstractControl{
private List controlList = new ArrayList<>();
private String name;
public Panel(String name) {
this.name = name;
}
@Override
public void add(AbstractControl control) {
controlList.add(control);
}
@Override
public void remote(AbstractControl control) {
control.remote(control);
}
@Override
public AbstractControl getChild(int i) {
return controlList.get(i);
}
@Override
public void show() {
//比如要展示子类的所有内容或调用子类的所有业务方法,需要递归调用成员构件的方法
for (AbstractControl control : controlList) {
control.show();
}
}
}
//客户端
public class Client {
public static void main(String[] args) {
/**
* 案例需求描述:
* 要开发一个界面控件库,界面控件库分为两大类,一类是单元控件,例如按钮、文本框等,
* 一类是容器控件,例如窗体、中间面板等。
* 试用组合模式设计该组件控件库。
*/
//针对抽象构件编程
AbstractControl control1,control2,control3,control4,control5,control6,control7,control8,control9;
control1 = new Window("左边栏窗口");
control2 = new Window("右边栏窗口");
control3 = new Panel("右边栏面板");
control4 = new Panel("右边栏面板");
control5 = new ButtonControl("确认按钮");
control6 = new TextControl("标题");
control7 = new ButtonControl("取消按钮");
control8 = new TextControl("正文");
control9 = new ButtonControl("点赞按钮");
control1.add(control5);
control2.add(control6);
control3.add(control7);
control4.add(control8);
control1.add(control9);
//模拟点击某个界面控件
control2.show();
AbstractControl child = control1.getChild(0);
child.show();
AbstractControl child1 = control5.getChild(0);
}
}
【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。
【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git