设计模式 10 装饰器模式

装饰器模式(Decorator Pattern)属于 结构型模式

装饰,顾名思义,就是在原有基础上增添东西以显示更好的效果。

生活中非常多这样的例子, 衣服饰品珠宝首饰房子装修都是在进行装饰。

开发中这样的情况也非常多,比如用户的 性别在数据库表中一般都是存的编码,然后通过字典表进行翻译,进而在页面展示为男、女。

这里以用户服务的 查询为例介绍装饰器模式:

1、定义用户服务

/**
 * 用户服务
 */
public interface UserService {

    /**
     * 查询
     */
    public void query();
}

2、实现用户服务

/**
 * 用户服务实现类
 */
public class UserServiceImpl implements UserService {

    @Override
    public void query() {
        System.out.println("查询了一个用户");
    }
}

3、定义装饰器

/**
 * 装饰器
 */
public class Decorator implements UserService{

    /**
     * 用户服务
     * 定义为 protected 是为了方便子类的后置处理器使用
     */
    protected UserService userService;

    /**
     * 装饰用户服务
     * @param userService 用户服务
     */
    public Decorator(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void query() {
        userService.query();
    }
}

4、定义装饰器后置处理器

/**
 * 装饰器后置处理器
 */
public class DecoratorPostProcessor extends Decorator{

    /**
     * 使用父类的装饰器装饰用户服务
     * @param userService 用户服务
     */
    public DecoratorPostProcessor(UserService userService) {
        super(userService);
    }

    @Override
    public void query() {

        userService.query();
        // 后置处理
        System.out.println("查找字典表给性别赋值");
    }
}

5、调用

// 装饰用户服务实现类(注意,这里需要用装饰器后置处理器装饰,因为后置处理的业务逻辑写在里面)
Decorator decorator = new DecoratorPostProcessor(new UserServiceImpl());
// 调用装饰后的查询方法
decorator.query();

输出结果:

查询了一个用户
查找字典表给性别赋值

6、嵌套使用

在开发场景中,有时候一次后置处理并不能得到预期的数据(比如 数字转化为编码,编码再转化为名称),需要再次处理,此时再去定义一个装饰器是没有必要的,可以嵌套使用。

// 嵌套使用
DecoratorPostProcessor decorator1 = new DecoratorPostProcessor(decorator);
decorator1.query();

输出结果:

查询了一个用户
查找字典表给性别赋值
查找字典表给性别赋值

这样只需要在后置处理做判断需要处理的为数字还是编码即可实现嵌套装饰的效果。

可以发现,装饰器模式与前面介绍的代理模式在 结构上是一样的。对 装饰器模式来说,装饰者和被装饰者都实现同一个接口或抽象类;对 代理模式来说,代理类和被代理的类都实现同一个接口或抽象类,在结构上确实没有区别。

但是它们的 作用不同装饰器模式强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能,增强后你还是你,只是被强化了; 代理模式强调要让别人帮你去做事情,以及添加一些与你本身的业务没有太多关系的事情(记录日志、设置缓存等),重点在于让别人帮你做。

因此,装饰模式和代理模式的不同之处不在于实现方式,在于 用途思想

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

多层装饰比较复杂。

1、扩展一个类的功能。

2、动态增加功能,动态撤销。

可代替继承。

Original: https://www.cnblogs.com/codesail/p/16573988.html
Author: 程序航
Title: 设计模式 10 装饰器模式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/714997/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 关于力场

    1.概念陈述 接触力(contact force):只有相互接触才会发生的力叫做接触力,接触力分为弹性力和摩擦力,因为它们在本质上都是由电磁场引起的,属于电磁力. 非接触力(non…

    技术杂谈 2023年5月31日
    079
  • npm常用命令

    npm install npm install=npm i。在git clone项目的时候,项目文件中并没有 node_modules文件夹,项目的依赖文件可能很大。直接执行,np…

    技术杂谈 2023年7月11日
    073
  • Timer

    public class Timer1 { private final TaskQueue queue = new TaskQueue();//这是&#…

    技术杂谈 2023年5月31日
    078
  • go源码解读

    https://www.cnblogs.com/ricklz/category/1217225.html?page=1 Original: https://www.cnblogs….

    技术杂谈 2023年5月30日
    072
  • 全新升级的AOP框架Dora.Interception[4]: 基于表达式的拦截器注册

    基于特性标注的拦截器注册方式仅限于将拦截器应用到自己定义的类型上,对于第三方提供的类型就无能为力了。对于Dora.Interception(github地址,觉得不错不妨给一颗星)…

    技术杂谈 2023年5月31日
    062
  • 使用ansible时显示Failed to connect to the host via ssh【转】

    fatal: [192.168.0.2]: UNREACHABLE! => {“changed”: false, “msg”:…

    技术杂谈 2023年5月31日
    080
  • 前端工作流规范

    使用GitFlow, 在项目中会存在两个长期分支,主分支(master) 和 开发分支(develop)。 主分支(master): 该主分支代码用于对外发布的代码(一般指线上已经…

    技术杂谈 2023年6月1日
    079
  • APACHE快速安装流程梳理

    快速安装开始: 【环境配置1】 yum -y install gcc gcc-c++ wget 保留操作(可跳过): yum -y removeapr-util-devel apr…

    技术杂谈 2023年7月10日
    046
  • 企业级开发平台的演进

    过去几年中,现代软件开发的整体环境发生了巨大的变化。回想在 2000 年代初期,产业的发展并没有那么快,技术和框架只是在稳步前进。而现在,技术发展的复杂度和多样性已经可以用超音速来…

    技术杂谈 2023年6月21日
    0102
  • Android:Jetpack之视图绑定——ViewBinding

    1.Jetpack简介 手机厂商还没卷完Android 12, Android 13就悄然声息地来了,距离Google 2008年9月22日发布Android 1.0,已过去13个…

    技术杂谈 2023年7月10日
    076
  • LDD3源码分析之poll分析

    编译环境:Ubuntu 10.10 内核版本:2.6.32-38-generic-pae LDD3源码路径:examples/scull/pipe.c examples/scull…

    技术杂谈 2023年5月31日
    054
  • tar、gzip、zip、jar是什么,怎么查看?

    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。 如果你是后端程序员,我想你一定见过 *.tar.gz、 *.zip、 *.jar后缀的文件吧,这些都…

    技术杂谈 2023年7月25日
    070
  • SpringMVC详解

    SpringMVC的介绍 【1】Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就已包含在Spring框架中。正式名称” Spri…

    技术杂谈 2023年7月24日
    080
  • ncurses库的一些函数

    为了实现一个简单的聊天程序,如果使用普通的输入输出函数,会很凌乱。so,便想着能不能用下ncurses这个字符图形库 总结一下,就是这样。 使用ncurses时,先需要初始化窗口,…

    技术杂谈 2023年6月21日
    0117
  • IIS8的SNI功能实现同一服务器多HTTPS站点

    名词解释: SNI指是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用。它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHel…

    技术杂谈 2023年5月31日
    0105
  • 一文读懂数据库发展史

    本文力求以简单易懂的语言描述出数据库发展史,尽量避免出现复杂的概念介绍。数据库演进史如图1所示: 图1 数据库演进 一、穿孔纸带和文件系统 在现代意义的数据库出现之前(20世纪60…

    技术杂谈 2023年7月25日
    088
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球