装饰模式

1. 什么是装饰模式

Decorator 模式又叫做装饰模式、包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。

2. 装饰模式的结构

14_装饰模式 - 图1

3. 装饰模式的角色和职责

  • 抽象组件角色:一个抽象接口,是被装饰类和装饰类的父接口。
  • 具体组件角色:为抽象组件的实现类。
  • 抽象装饰角色:包含一个组件的引用,并定义了与抽象组件一致的接口。
  • 具体装饰角色:为抽象装饰角色的实现类。负责具体的装饰。

4. 代码演示

4.1. 直接创建

  1. public class Car {
  2. public void run() {
  3. System.out.println("可以跑");
  4. }
  5. public void fly() {
  6. System.out.println("可以飞");
  7. }
  8. public void swim() {
  9. System.out.println("可以游");
  10. }
  11. public void show() {
  12. System.out.println("拥有的功能");
  13. this.run();
  14. this.fly();
  15. this.swim();
  16. }
  17. }
  1. Car car = new Car();
  2. car.show();

所有车都会飞、会游显然不合理,但是又需要有的车会飞,有的车会游,有的既会飞又会游。

4.2. 使用继承

  1. public interface Car {
  2. void run();
  3. void show();
  4. }
  1. public class RunCar implements Car {
  2. @Override
  3. public void run() {
  4. System.out.println("可以跑");
  5. }
  6. @Override
  7. public void show() {
  8. this.run();
  9. }
  10. }
  1. public class FlyCar implements Car {
  2. @Override
  3. public void run() {
  4. System.out.println("可以跑");
  5. }
  6. public void fly() {
  7. System.out.println("可以飞");
  8. }
  9. @Override
  10. public void show() {
  11. this.run();
  12. this.fly();
  13. }
  14. }
  1. public class SwimCar implements Car {
  2. @Override
  3. public void run() {
  4. System.out.println("可以跑");
  5. }
  6. public void swim() {
  7. System.out.println("可以游");
  8. }
  9. @Override
  10. public void show() {
  11. this.run();
  12. this.swim();
  13. }
  14. }
  1. Car runCar = new RunCar();
  2. runCar.show();
  3. System.out.println("==========");
  4. Car flyCar = new FlyCar();
  5. flyCar.show();
  6. System.out.println("==========");
  7. Car swimCar = new SwimCar();
  8. swimCar.show();
  1. 可以跑
  2. ==========
  3. 可以跑
  4. 可以飞
  5. ==========
  6. 可以跑
  7. 可以游

当功能组合很多时,使用继承方式…

4.3. 使用装饰

4.3.1. 抽象组件

  1. public interface Car {
  2. void run();
  3. void show();
  4. }

4.3.2. 具体组件

  1. public class RunCar implements Car {
  2. @Override
  3. public void run() {
  4. System.out.println("可以跑");
  5. }
  6. @Override
  7. public void show() {
  8. this.run();
  9. }
  10. }

4.3.3. 抽象装饰

  1. public abstract class CarDecorator implements Car {
  2. private final Car car;
  3. public CarDecorator(Car car) {
  4. this.car = car;
  5. }
  6. public Car getCar() {
  7. return car;
  8. }
  9. @Override
  10. public abstract void run();
  11. @Override
  12. public abstract void show();
  13. }

4.3.4. 具体装饰

  1. public class FlyCarDecorator extends CarDecorator {
  2. public FlyCarDecorator(Car car) {
  3. super(car);
  4. }
  5. @Override
  6. public void run() {
  7. }
  8. @Override
  9. public void show() {
  10. this.getCar().show();
  11. this.fly();
  12. }
  13. public void fly() {
  14. System.out.println("可以飞");
  15. }
  16. }
  1. public class SwimCarDecorator extends CarDecorator {
  2. public SwimCarDecorator(Car car) {
  3. super(car);
  4. }
  5. @Override
  6. public void run() {
  7. }
  8. @Override
  9. public void show() {
  10. this.getCar().show();
  11. this.swim();
  12. }
  13. public void swim() {
  14. System.out.println("可以游");
  15. }
  16. }

4.3.5. 扩展一个功能

  1. Car car = new RunCar();
  2. Car flyCar = new FlyCarDecorator(car);
  3. flyCar.show();
  1. 可以跑
  2. 可以飞

4.3.6. 分别扩展多个功能

  1. Car car = new RunCar();
  2. Car flyCar = new FlyCarDecorator(car);
  3. flyCar.show();
  4. System.out.println("==========");
  5. Car swimCar = new SwimCarDecorator(car);
  6. swimCar.show();
  1. 可以跑
  2. 可以飞
  3. ==========
  4. 可以跑
  5. 可以游

4.3.7. 同时扩展多个功能

  1. Car car = new RunCar();
  2. car.show();
  3. System.out.println("==========");
  4. Car flyCar = new FlyCarDecorator(car);
  5. flyCar.show();
  6. System.out.println("==========");
  7. Car flySwimCar = new SwimCarDecorator(flyCar);
  8. flySwimCar.show();
  1. 可以跑
  2. ==========
  3. 可以跑
  4. 可以飞
  5. ==========
  6. 可以跑
  7. 可以飞
  8. 可以游