装饰器模式(Decorator Pattern)

概念

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式类似于俄罗斯套娃;

简介

作用及优势

  • 不会改变原有的逻辑,对之前的功能无侵入性
  • 扩展性更好,可以在装饰器类里面加独立的功能
  • 装饰器跟原有的类,两者功能是解耦的

不足之处

如果存在多层的装饰,那就会使得逻辑变得比较复杂;

场景

  • java中IO里面很多操作 :new BufferedReader(newFileReader(""))

代码

案例描述

假设我有辆装逼的机车(Locomotive),虽然很装逼,但是总感觉有点不足,那个轰鸣声虽然大;但是不够,于是我想改造,装个音箱来放dj(装饰物:音箱),这个时候我还需要一个放音箱的架子(CarDecorator);然后我把音箱放上去就可以快乐的听dj了,快乐的装逼了!!

是时候出来装逼了.gif

工程目录

image.png

项目类图

装饰器模式.jpg

具体实现

接口Car :车,有驾驶的功能

/**
 * 功能描述: 抽象类 车
 *
 * @author: WuChengXing
 * @create: 2021-07-09 23:41
 **/
public interface Car {

    void drive();
}

有两个子实现:机车(Locomotive)、自行车(Bicycle)

/**
 * 功能描述: 机车
 *
 * @author: WuChengXing
 * @create: 2021-07-09 23:40
 **/
public class Locomotive implements Car {

    @Override
    public void drive() {
        System.out.println("=== 开着我装逼大机车... ===");
    }
}

---------------------------------------------

/**
 * 功能描述: 自行车
 *
 * @author: WuChengXing
 * @create: 2021-07-09 23:42
 **/
public class Bicycle implements Car {
    @Override
    public void drive() {
        System.out.println("=== 骑着我心爱的小毛驴... ===");
    }
}

抽象装饰类:CarDecorator

/**
 * 功能描述: 装饰器,理解为可以给机车装上或者小毛驴装饰一些东西
 *
 * @author: WuChengXing
 * @create: 2021-07-09 23:43
 **/
public abstract class CarDecorator implements Car{
    private Car car;

    public CarDecorator(Car car) {
        this.car = car;
    }

    @Override
    public void drive() {
        car.drive();
    }
}

具体装饰类:SpeakerDecorator

/**
 * 功能描述: 音箱
 *
 * @author: WuChengXing
 * @create: 2021-07-09 23:47
 **/
public class SpeakerDecorator extends CarDecorator {
    public SpeakerDecorator(Car car) {
        super(car);
    }

    @Override
    public void drive() {
        super.drive();
        play();
    }

    public void play(){
        System.out.println("=== 来点音乐助助兴 ===");
    }
}

这里除了机车原始的功能,还给他加上了 DJ 的功能;

测试

/**
 * 功能描述: 测试类
 *
 * @author: WuChengXing
 * @create: 2021-07-09 23:37
 **/
public class DecoratorTest {
    public static void main(String[] args) {
        // 最原始的机车
        Car locomotive = new Locomotive();
        // 装上了音乐的机车
        SpeakerDecorator speakerDecorator = new SpeakerDecorator(locomotive);
        System.out.println("----- 最原始的机车 -----");
        locomotive.drive();
        System.out.println("----- 装上了音乐的机车 -----");
        speakerDecorator.drive();
        System.out.println("----- 单纯想听点音乐 -----");
        speakerDecorator.play();
    }
}

结果: 这里可以看到,装饰类和原有的类功能都是独立的,并不会互相影响;

----- 最原始的机车 -----
=== 开着我装逼大机车... ===
----- 装上了音乐的机车 -----
=== 开着我装逼大机车... ===
=== 来点音乐助助兴 ===
----- 单纯想听点音乐 -----
=== 来点音乐助助兴 ===