设计模式之装饰者模式

一、什么是装饰者模式

装饰者模式,在不改变现有对象结构的情况下,动态地给一个对象添加一些额外的职责,扩展了被装饰者的功能。可以说装饰者模式非常符合OCP原则“对修改关闭,对扩展开放”,是比继承更有弹性的替代方案,比生产子类更加灵活。

二、装饰者模式类图

设计模式之装饰者模式插图

三、装饰者模式角色

  • 抽象构件角色(Component):定义一个对象接口或抽象类,可以给这些对象动态地添加职责。
  • 具体构件角色(ConcreteComponent): 实现抽象构件接口,通过装饰者角色为其动态添加职责。
  • 抽象装饰者角色(Decorator):继承或实现抽象构件,并关联具体构件的实例对象,可以通过其子类开展具体构件的功能。
  • 具体装饰者角色(ConcreteDecorator): 实现抽象装饰者的抽象方法,并给具体构件动态地添加职责。

四、装饰者模式优缺点

优点:

  1. 装饰者模式提供了比继承更多的灵活性,使用更加方便,防止了“类爆炸”。
  2. 通过使用不同的具体装饰者类及它们之间的组合顺序,可以得到不同装饰后具有不同行为或状态的对象。
  3. 符合OCP原则。

缺点:

  1. 增加了抽象装饰者类和具体装饰者类,一定程度上增加了系统的复杂度。
  2. 灵活性也意味着更容易出错,一定程度上增加了排错的难度。

五、装饰者模式demo示例

1、Demo需求

小汽车都能飞快地跑起来,有的可以在陆地上跑,有的可以在水上跑,还有的可以天上飞、无人驾驶等功能,现在要对小汽车进行升级,实现比如既可以陆地上跑,也可以水里跑;还可以无人驾驶的同时在水里跑等等需求。

2、接口及抽象类定义

/**
  * 抽象构建角色接口
  */ public interface ICar {

     void run();
 }
/**
  * 抽象装饰器角色:汽车装饰器类
  */ public abstract class AbstractCarDecorator implements ICar {

     protected ICar car;

     public AbstractCarDecorator(ICar iCar){
         this.car = iCar;
     }

     public void run() {
         car.run();
     }
 }

3、实现类定义

/**
  * 具体构建实现子类-具体被装饰者对象
  */ public class Car implements ICar {
 
     public void run() {
         System.out.println("汽车在陆地上跑!");
     }
 }
/**
  * 具体装饰者类:会飞的汽车
  */ public class FlyCar extends AbstractCarDecorator {

     public FlyCar(ICar iCar) {
         super(iCar);
     }
 
     @Override
     public void run() {
         car.run();
         System.out.println("汽车在天上飞!");
     }
 }
/**
  * 具体装饰者类:无人驾驶汽车
  */ public class AICar extends AbstractCarDecorator {

     public AICar(ICar iCar) {
         super(iCar);
     }
 
     @Override
     public void run() {
         car.run();
         System.out.println("汽车能无人驾驶!");
     }
 }
/**
  * 具体装饰者类:水中跑的汽车
  */ public class WaterCar extends AbstractCarDecorator {

     public WaterCar(ICar iCar) {
         super(iCar);
     }
 
     @Override
     public void run() {
         car.run();
         System.out.println("汽车在水上游!");;
 
     }
 }

4、测试

public class Client {

     public static void main(String[] args) {
         ICar car = new Car();
         car.run();
         System.out.println("======================");
 
         ICar flyCar = new FlyCar(car);
         flyCar.run();
         System.out.println("=======================");
         ICar waterCar = new WaterCar(flyCar);
         waterCar.run();
         System.out.println("========================");
         AICar aiCar = new AICar(waterCar);
         aiCar.run();
     }
 }
汽车在陆地上跑!
======================
汽车在陆地上跑!
汽车在天上飞!
=======================
汽车在陆地上跑!
汽车在天上飞!
汽车在水上游!
========================
汽车在陆地上跑!
汽车在天上飞!
汽车在水上游!
汽车能无人驾驶!

发表评论