首页 > 编程笔记 > Java笔记 阅读:27

组合模式(Java实现)

如果想用同一套方式来统一处理不同的对象,并将其安排成树状结构以方便访问,那么组合模式会是一个相当好的方案。

对软件开发行业来说,这样的需求很自然,因此组合模式很早就出现了,而且是一种经典的 GoF 设计模式。

根据底层业务逻辑给对象归组是个很有用的做法。组合模式能够帮助我们实现这样的效果。它用一套相同的办法对待群组中的各类对象,让我们能够方便地创建出有层次的树状结构,并表示出整体与部分之间的关系。这个模式使得应用程序的代码更有逻辑,而且让相关对象之间的组合关系更加明显。

组合模式在JDK中的运用

JDK 的 Properties 类用到了组合模式,该类位于 java.base 模块的 java.util 包中。

Properties 类通过继承 Hashtable 类而实现 Map 接口,另外,该类内部还组合了一个 ConcurrentHashMap,用来保存属性值,这个 ConcurrentHashMap 也实现了 Map 接口。于是,Java 系统就可以通过 Map 接口来统一对待 Properties 以及它里面组合的那个 ConcurrentHashMap了。

Map 接口定义了 put() 与 get() 等方法,Properties 类的 put() 方法是从 Hashtable 类继承下来的,因此是个同步(synchronized)方法。但它的 get() 方法却是自己覆写的,这个方法不是 synchronized 方法,因为该方法只需要从内部的 ConcurrentHashMap 里把相关的属性值读取出来就好,所以不需要像超类 Hashtable 的 get() 方法那样也设计成 synchronized 方法。

组合模式范例

我们用 SportVehicle 类来演示组合模式的功效,该类实现了表示车辆的 Vehicle 接口。

除了 Vehicle 接口,它还与车辆里的部件(也就是 VehiclePart)一样都实现 VehicleElement 接口,这让我们能够用同一种方式(也就是 VehicleElement 接口定义的方式)来操纵车辆本身以及它里面的部件,参见下图。


程序把车辆的各个部件(以及某些部件里面小部件)装配完毕之后,我们就可以在车辆的 parts 列表中观察所有部件的状态了。
public static void main(String[] args) {
    System.out.println("Pattern Composite, vehicle parts...");
    var fastVehicle = new SportVehicle("sport");
    var engine = new VehiclePart("fast-engine");
    engine.addPart(new VehiclePart("cylinder-head"));
    var brakes = new VehiclePart("super-brakes");
    var transmission = new VehiclePart("automatic-transmission");
    fastVehicle.addPart(engine);
    fastVehicle.addPart(brakes);
    fastVehicle.addPart(transmission);
    fastVehicle.printParts();
}
程序输出结果如下:

Pattern Composite, vehicle parts...
SportCar, type'sport', parts:
[{type='fast-engine', parts=[{type='cylinder-head', parts=[]}]},
{type='super-brakes', parts=[]},
{type='automatic-transmission', parts=[]}]

相关文章