瞎说设计模式第七回:组合模式
Posted 竹森技术分享
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了瞎说设计模式第七回:组合模式相关的知识,希望对你有一定的参考价值。
上一篇,通过车辆定制来说了说桥接模式,今天我们来聊聊组合模式。思来想去,就用车子启动前的自检来说吧。
大多数车子通电之后,会进行一遍自检,把全车各个部分组件迅速地检查一遍。一些组件是一级组件,一些是一级组件下的二级组件等。
总的来说,自检的范围包括机械部分、电器部分和油液部分等。
我们来设计这样一个自检系统。
首先,建立一个所有组件的抽象类,定义一些抽象的基本行为:
public abstract class AbstractCompont {
public abstract void add(AbstractCompont compont);
public abstract void remove(AbstractCompont compont);
public abstract AbstractCompont getChild(int i);
public abstract void checkHealth();
}
接下来,分别实现机械、电器和油液三个部分的组件类。
机械组件类:
public class MechanicalCompont extends AbstractCompont {
private String name;
public MechanicalCompont(String name) {
this.name = name;
}
public void add(AbstractCompont compont) {
System.out.println("不支持该方法");
}
public void remove(AbstractCompont compont) {
System.out.println("不支持该方法");
}
public AbstractCompont getChild(int i) {
System.out.println("不支持该方法");
return null;
}
public void checkHealth() {
//模拟组件健康检查
System.out.println("启动自检,对机械部分——" + name + "进行健康检查");
}
}
电器组件类:
public class ElectricalCompont extends AbstractCompont {
private String name;
public ElectricalCompont(String name) {
this.name = name;
}
public void add(AbstractCompont compont) {
System.out.println("不支持该方法");
}
public void remove(AbstractCompont compont) {
System.out.println("不支持该方法");
}
public AbstractCompont getChild(int i) {
System.out.println("不支持该方法");
return null;
}
public void checkHealth() {
//模拟组件健康检查
System.out.println("启动自检,对电器部分——" + name + "进行健康检查");
}
}
油液组件类:
public class OilAndLiquidCompont extends AbstractCompont {
private String name;
public OilAndLiquidCompont(String name) {
this.name = name;
}
public void add(AbstractCompont compont) {
System.out.println("不支持该方法");
}
public void remove(AbstractCompont compont) {
System.out.println("不支持该方法");
}
public AbstractCompont getChild(int i) {
System.out.println("不支持该方法");
return null;
}
public void checkHealth() {
//模拟组件健康检查
System.out.println("启动自检,对油液部分——" + name + "进行健康检查");
}
}
然后,实现一个上层组件类,也就是开头说的一级组件:
public class SuperCompont extends AbstractCompont {
private String name;
private ArrayList<AbstractCompont> componts = new ArrayList<>();
public SuperCompont(String name) {
this.name = name;
}
public void add(AbstractCompont compont) {
componts.add(compont);
}
public void remove(AbstractCompont compont) {
componts.remove(compont);
}
public AbstractCompont getChild(int i) {
return componts.get(i);
}
public void checkHealth() {
System.out.println("启动自检,对" + name + "进行健康检查");
for (AbstractCompont compont : componts
) {
compont.checkHealth();
}
}
}
最后,定义一个自检控制类,实现自检的组合:
public class CheckController {
public static void main(String args[]) {
AbstractCompont superCar = new SuperCompont("全车");
AbstractCompont superMechanical = new SuperCompont("机械部分");
AbstractCompont superElectrical = new SuperCompont("电器部分");
AbstractCompont superOilAndLiquid = new SuperCompont("油液部分");
AbstractCompont engine = new MechanicalCompont("发动机系统");
AbstractCompont gearbox = new MechanicalCompont("变速箱系统");
AbstractCompont chassis = new MechanicalCompont("底盘系统");
superMechanical.add(engine);
superMechanical.add(gearbox);
superMechanical.add(chassis);
AbstractCompont powerSupply = new ElectricalCompont("电源系统");
AbstractCompont startUp = new ElectricalCompont("启动系统");
AbstractCompont ignition = new ElectricalCompont("点火系统");
AbstractCompont light = new ElectricalCompont("照明系统");
AbstractCompont signal = new ElectricalCompont("信号系统");
AbstractCompont meter = new ElectricalCompont("仪表系统");
AbstractCompont ecu = new ElectricalCompont("电控系统");
superElectrical.add(powerSupply);
superElectrical.add(startUp);
superElectrical.add(ignition);
superElectrical.add(light);
superElectrical.add(signal);
superElectrical.add(meter);
superElectrical.add(ecu);
AbstractCompont fuelOil = new OilAndLiquidCompont("燃油情况");
AbstractCompont lubricatingOil = new OilAndLiquidCompont("机油情况");
AbstractCompont transmissionOil = new OilAndLiquidCompont("变速箱油情况");
AbstractCompont coolant = new OilAndLiquidCompont("冷却液情况");
AbstractCompont washerFluid = new OilAndLiquidCompont("玻璃水情况");
superOilAndLiquid.add(fuelOil);
superOilAndLiquid.add(lubricatingOil);
superOilAndLiquid.add(transmissionOil);
superOilAndLiquid.add(coolant);
superOilAndLiquid.add(washerFluid);
superCar.add(superMechanical);
superCar.add(superElectrical);
superCar.add(superOilAndLiquid);
superCar.checkHealth();
}
}
运行结果如下:
启动自检,对全车进行健康检查
启动自检,对机械部分进行健康检查
启动自检,对机械部分——发动机系统进行健康检查
启动自检,对机械部分——变速箱系统进行健康检查
启动自检,对机械部分——底盘系统进行健康检查
启动自检,对电器部分进行健康检查
启动自检,对电器部分——电源系统进行健康检查
启动自检,对电器部分——启动系统进行健康检查
启动自检,对电器部分——点火系统进行健康检查
启动自检,对电器部分——照明系统进行健康检查
启动自检,对电器部分——信号系统进行健康检查
启动自检,对电器部分——仪表系统进行健康检查
启动自检,对电器部分——电控系统进行健康检查
启动自检,对油液部分进行健康检查
启动自检,对油液部分——燃油情况进行健康检查
启动自检,对油液部分——机油情况进行健康检查
启动自检,对油液部分——变速箱油情况进行健康检查
启动自检,对油液部分——冷却液情况进行健康检查
启动自检,对油液部分——玻璃水情况进行健康检查
我们回顾一下组合模式的定义:将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。(摘自GoF的《设计模式》)
在车辆自检的例子中,通过AbstractCompont抽象类的各种继承,实现了“单个对象和组合对象的使用具有一致性”,而从全车—部分—系统实现了对对象组合成了树形结构来表示了“部分—整体”的层次结构。在自检控制类CheckController中,可以控制对全局的自检和部分自检,同时,如果有新的自检项目加入时,只需要继承AbstractCompont抽象类,并在CheckController进行灵活组合即可,符合开闭原则。
以上是关于瞎说设计模式第七回:组合模式的主要内容,如果未能解决你的问题,请参考以下文章
第七课-第二讲 07_02_bash脚本编程之六 使用脚本选项及组合条件测试