一文看懂什么是装饰器模式【没有废话,很硬】

写在前面

前面提到,需要对类功能增强 ,可以使用继承,代理模式,装饰器模式,还有Scala的隐式转换技术。本篇主要介绍一下装饰器模式。

那么接下来就开始吧,如果有什么错误的地方,欢迎指正~我也还在不断的学习中,大家一起加油!
在这里插入图片描述

装饰器扩展功能就是 新增一个装饰器类。

装饰器模式

1.1 来一个接口:
写一个程序员的接口,当然程序员嘛,本质工作当然是写代码了,所以这个接口我们可以定义一个coding的方法。

public interface Programmer {
    
    
    void coding();
}

1.2 实现这个接口

我自己也是一名苦逼的程序员,我也可以去实现这个接口啦~
如下:Liuge36 implements Programmer

public class Liuge36 implements Programmer {
    
    
    public void coding() {
    
    
        System.out.println("留歌是一个程序员,每天的工作就是写代码...【这是留歌作为程序员的本质】");
    }
}

1.3 装饰器模式的实现
我们得写一个装饰器类ProgrammerDecorate,这是一个抽象类 去实现我们 Programmer 这个接口。以 Programmer 接口作为 ProgrammerDecorate 构造函数 的参数。

public abstract class ProgrammerDecorate implements Programmer {
    
    
    // 以 Programmer 接口作为 本抽象类 构造方法 的参数
    protected Programmer programmer;

    // 构造方法
    public ProgrammerDecorate(Programmer decorateProgrammer){
    
    
        this.programmer = decorateProgrammer;
    }

    public void coding() {
    
    
        programmer.coding();
    }
}

为啥突然写一个这个玩意呢?主要是因为我们后续 功能的扩展 都是基于这个装饰器类来实现的,我们增强类直接继承这个 装饰器类 就好

1.4 这个时候想要知道留歌以前到现在的状态,咋个办呢?我们需要进行功能的增强,写一个方法来描述留歌过去的状态。

^_^  ^_^   
public class BeforeLiuge36Dec extends ProgrammerDecorate{
    
    

    /**
     * 我感觉这里也算核心之一,其实后面传递进来的对象,都是这个接口 实现类的 实例
     * @param programmer
     */
    public BeforeLiuge36Dec(Programmer programmer) {
    
    
        super(programmer);
    }

    /**
     * 重写coding方法
     */
    @Override
    public void coding() {
    
    

        draw();

        super.coding();
    }


    /**
     * 进行功能的增强
     */
    public void draw(){
    
    
        System.out.println("留歌在这之前呢,其实也是画画的?");
    }
}


1.5 我们现在又想知道留歌最近在学习写什么?又需要写一个类进行增强

public class BeforeLiuge36Dec extends ProgrammerDecorate{
    
    

    /**
     * 我感觉这里也算核心之一,其实后面传递进来的对象,都是这个接口 实现类的 实例
     * @param programmer
     */
    public BeforeLiuge36Dec(Programmer programmer) {
    
    
        super(programmer);
    }

    /**
     * 重写coding方法
     */
    @Override
    public void coding() {
    
    

        draw();

        super.coding();
    }


    /**
     * 进行功能的增强
     */
    public void draw(){
    
    
        System.out.println("留歌在这之前呢,其实也是画画的?");
    }
}

1.6 测试一下


public class TestDecorator {
    
    
    public static void main(String[] args) {
    
    
        // 单调的 Liuge36
        Programmer liuge36 = new Liuge36();
        liuge36.coding();

        System.out.println("================写代码之前的留歌的状态=======================");

        // 装饰过得 Liuge36
        liuge36 = new BeforeLiuge36Dec(liuge36);
        liuge36.coding();

        System.out.println("================写代码之后的留歌的状态=======================");

        // 装饰过得 Liuge36
        liuge36 = new AfterLiuge36Dec(liuge36);
        liuge36.coding();
        
    }
}

在这里插入图片描述
结果:
在这里插入图片描述

装饰模式的优缺点

优点:

装饰类和被装饰类是可以独立的,低耦合的。互相都不用知道对方的存在

装饰模式是继承的一种替代方案,无论包装多少层,返回的对象都是is-a的关系(上面的例子:包装完还是Phone类型)。

实现动态扩展,只要继承了装饰器就可以动态扩展想要的功能了。

缺点:

多层装饰是比较复杂的,提高了系统的复杂度。不利于我们调试~

装饰模式其实在IO那块用得比较多

参考:
https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA

猜你喜欢

转载自blog.csdn.net/liuge36/article/details/106401467