设计模式初阶——装饰者模式

一、什么是装饰者模式? 【设计模式初阶——装饰者模式】简而言之,装饰者模式是一种可以动态地、灵活地将所需要的功能加到主体上去的设计模式。
我们来考虑这样一个场景,先来设计一辆车,这辆车最初只能在地上跑,当然这也是作为车的基本需求。然而随着科技的进步和市场的要求,我们需要将它改装为能具有飞行能力的第二代车,随后我们又需要将其改装成具有在水上航行能力的第三代车。当然,我们也可以基于第一代车,给其增加在水上航行的能力,而不增加飞行的能力。怎么改装取决于需要。看到没,这样就是可以动态地、灵活地给车主体增加功能。
具体的代码示例如下:

public abstract class Vehicle { public abstract void run(); }

public class JeepCar extends Vehicle { @Override public void run() { System.out.println("can run on the ground"); } }

如上,我们就实现了可以在陆地上跑的第一代车。现在我们需要给其加上飞行和航行的能力:
public abstract class VehicleDecorator extends Vehicle { // 额外的其它功能 public abstract void sleep(); }

public class PlaneWrapper extends VehicleDecorator { private Vehicle vehicle; public PlaneWrapper(Vehicle vehicle){ this.vehicle = vehicle; } @Override public void run() { System.out.println("can fly in the air"); vehicle.run(); } @Override public void sleep() { System.out.println("can sleep on the plane"); } }

public class ShipWrapper extends VehicleDecorator { private Vehicle vehicle; public ShipWrapper(Vehicle vehicle){ this.vehicle = vehicle; } @Override public void run() { System.out.println("can swim in the water"); vehicle.run(); } @Override public void sleep() { System.out.println("can sleep on the ship"); } }

我们可以看到,第二代和第三代的车都不是直接继承Vehicle的,这是为什么呢?
答案是为了方便地扩展第二代和第三代车的其它功能,这些额外的功能也许是某一代车所特有的,同时也是作为一个装饰器抽象后续所有的迭代车系列。当然,在这里,你也可以让第二代和第三代车直接继承Vehicle,这也是没什么问题的。
最后,车终于做好了,可以开车了。
public class Test { public static void main(String[] args) { Vehicle jeep = new JeepCar(); System.out.println("***The first generation:***"); jeep.run(); PlaneWrapper jeep2 = new PlaneWrapper(jeep); System.out.println("***The second generation:***"); jeep2.run(); jeep2.sleep(); ShipWrapper jeep3 = new ShipWrapper(jeep2); System.out.println("***The third generation:***"); jeep3.run(); jeep3.sleep(); } }

执行的结果为:
***The first generation:*** can run on the ground ***The second generation:*** can fly in the air can run on the ground can sleep on the plane ***The third generation:*** can swim in the water can fly in the air can run on the ground can sleep on the ship

二、为什么要使用装饰者模式? 可以在不用改动原有逻辑的基础上动态、灵活地增加新的功能。
三、如何使用装饰者模式呢? 使用的要点如下:
  • 需要创建一个装饰器,继承实体的最顶层抽象;
  • 可以在装饰器里增加需要实现的额外的功能;
  • 需要创建新的实体类,继承装饰器,实现其最顶层的逻辑,同时实现在装饰器中新增的逻辑。

    推荐阅读