zoukankan      html  css  js  c++  java
  • 一文看懂什么是装饰器模式【没有废话,很硬】

    写在前面

    前面提到,需要对类功能增强 ,可以使用继承,代理模式,装饰器模式,还有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

  • 相关阅读:
    leetcode第14题最长公共前缀
    什么是神经网络
    获取url "?" 后面的字符串
    第一天
    C#和.Ne学习第九天
    C#和.Ne学习第八天
    格式化输出
    C#和.Ne学习
    C#和.Ne学习第七天
    C#类型转换
  • 原文地址:https://www.cnblogs.com/liuge36/p/13019734.html
Copyright © 2011-2022 走看看