浅谈Java设计模式系列-装饰器模式

 更新时间:2019年03月20日 14:31:36   作者:唯一浩哥  
这篇文章主要介绍了Java设计模式系列-装饰器模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、概述

装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能。

不同于适配器模式和桥接模式,装饰器模式涉及的是单方,和代理模式相同,而且目标必须是抽象的。

而实际上,装饰器模式和代理模式的实现方式基本一致,只在目标的存在上有些差别,这个后面我们具体讲述。

二、初步分析

上面提到了两点:

  1. 涉及的是单方
  2. 目标是抽象的

我们来想一下,所谓单方主要指的是在整个装饰器模式中不存在双方调用,要解决的也不是双方调用的问题,而是解决单方提供对外服务的问题,这个单方在自行对外提供服务时,功能不足,或者我们需要额外添加一些新功能,这时就可以使用装饰器模式,来对这个单方进行增强。

目标抽象的意思是因为我们需要通过实现接口的方式来进行增强,因此目标必须抽象为接口。

三、实例

下面我们用我们生活中的一个例子来说明,我们用房子来作为目标:
房子接口:House

/**
 * 目标接口:房子
 */
public interface House {
 void output();
}

 具体的房子:DonghaoHouse

/**
 * 房子实现类
 */
public class DonghaoHouse implements House {
 @Override
 public void output() {
  System.out.println("这是董浩的房子");
 }
}

具体的房子:DongliangHouse

/**
 * 房子实现类
 */
public class DongliangHouse implements House {
 @Override
 public void output() {
  System.out.println("这是董量的房子");
 }
}

装饰器:Decorator

public class Decorator implements House {
 private House house;
 public Decorator(House house){
  this.house = house;
 }
 @Override
 public void output() {
  System.out.println("这是针对房子的前段装饰增强");
  house.output();
  System.out.println("这是针对房子的后段装饰增强");
 }
}

测试类:

public class Clienter {
 public static void main(String[] args) {
  House donghaoHouse = new DonghaoHouse();
  House decorator = new Decorator(donghaoHouse);
  decorator.output();
 }
}

 执行结果为:

 这是针对房子的前段装饰增强
这是董浩的房子
这是针对房子的后段装饰增强

 四、解析

通过上面的例子我们可以看出,除了测试类外,只剩下接口和实现类了,即使是装饰器类也是目标接口的一个字类,这更能说明单方的说法,模式中所有的类都属于目标方。至于目标是抽象的更是如此,只有目标是抽象的,才可以使用装饰器模式来进行增强。

上面我们说过装饰器模式与代理模式基本相同,只存在少许差别。

我们需要从概念上了解代理和装饰的区别:

  1. 代理是全权代理,目标根本不对外,全部由代理类来完成。
  2. 装饰是增强,是辅助,目标仍然可以自行对外提供服务,装饰器只起增强作用。

上面两点提现到代码实现中是这样的:
代理模式

public class Proxy implements House {
 private House house;
 public Decorator(){
  this.house = new DonghaoHouse();
 }
 @Override
 public void output() {
  System.out.println("这是针对目标的前段增强");
  house.output();
  System.out.println("这是针对目标的后段增强");
 }
}

 装饰模式

public class Decorator implements House {
 private House house;
 public Decorator(House house){
  this.house = house;
 }
 @Override
 public void output() {
  System.out.println("这是针对房子的前段装饰增强");
  house.output();
  System.out.println("这是针对房子的后段装饰增强");
 }
}

看出来了吗,装饰器中持有的目标实例是从构造器传入的,而代理中持有的目标实例是自己创建的。

那么这里又出现一个区别,代理模式和装饰器模式虽然都依赖于目标接口,但是代理针对的目标实现类是固定的,而装饰器模式可以随意指定,也就是说目标是可以自有扩展的。

五、使用场景

装饰器模式就是使用在对已有的目标功能存在不足,需要增强时,前提是目标存在抽象接口。

六、总结

我们要明白代理模式和装饰器模式的区别,区分二者的使用场景,如下图:

以上所述是小编给大家介绍的Java设计模式系列-装饰器模式详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • SpringMVC配置javaConfig及StringHttpMessageConverter示例

    SpringMVC配置javaConfig及StringHttpMessageConverter示例

    这篇文章主要介绍了SpringMVC配置javaConfig及StringHttpMessageConverter实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • springBoot配置国产达梦数据库的示例详解

    springBoot配置国产达梦数据库的示例详解

    本文向大家介绍springBoot 配置国产达梦数据库的相关知识,文章结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • JavaWeb Maven详解相关配置

    JavaWeb Maven详解相关配置

    这篇文章主要介绍了使用maven架构管理开发的相关配置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 基于JavaMail实现邮件发送

    基于JavaMail实现邮件发送

    这篇文章主要为大家详细介绍了基于JavaMail实现邮件发送功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • java打jar包与找不到依赖包的问题

    java打jar包与找不到依赖包的问题

    这篇文章主要介绍了java打jar包与找不到依赖包的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java设计模式中的门面模式详解

    Java设计模式中的门面模式详解

    门面模式又叫外观模式(Facade Pattern),主要用于隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口,本文通过实例代码给大家介绍下java门面模式的相关知识,感兴趣的朋友一起看看吧
    2022-09-09
  • 如何解决org.apache.jasper.JasperException:无法为JSP编译类详解

    如何解决org.apache.jasper.JasperException:无法为JSP编译类详解

    这篇文章主要给大家介绍了关于如何解决org.apache.jasper.JasperException:无法为JSP编译类的相关资料,原因可能是JSP文件的语法错误、类路径问题或其他配置问题,建议检查JSP文件的语法、类路径配置和其他相关配置,需要的朋友可以参考下
    2023-06-06
  • SpringBoot服务上实现接口限流的方法

    SpringBoot服务上实现接口限流的方法

    这篇文章主要介绍了SpringBoot服务上实现接口限流的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Java圆柱体表面积和体积计算代码实例

    Java圆柱体表面积和体积计算代码实例

    这篇文章主要介绍了Java圆柱体表面积和体积计算代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • SpringBoot使用EmbeddedDatabaseBuilder进行数据库集成测试

    SpringBoot使用EmbeddedDatabaseBuilder进行数据库集成测试

    在开发SpringBoot应用程序时,我们通常需要与数据库进行交互,为了确保我们的应用程序在生产环境中可以正常工作,我们需要进行数据库集成测试,在本文中,我们将介绍如何使用 SpringBoot 中的 EmbeddedDatabaseBuilder 来进行数据库集成测试
    2023-07-07

最新评论