装饰器模式

定义:

  • 装饰者模式(Decorator Pattern)是指在不改变原有对象的基础之上,将一些新的功能动态的添加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。

组成:

案例 1:

需求:

  • Sourceable是抽象构建角色
  • Source类是具体的被装饰类
  • Decorator抽象装饰者
  • SpecificDecorator具体的装饰者

抽象构建角色 Sourceable

public interface Sourceable {void method();
}

具体被装饰类 Source

public class Source implements Sourceable {@Overridepublic void method() {System.out.println("the original method!");}
}

抽象装饰者 Decorator

public abstract class Decorator  implements Sourceable{private Sourceable source;public Decorator(Sourceable source) {super();this.source = source;}@Overridepublic void method() {source.method();}
}

具体的装饰者 SpecificDecorator

public class SpecificDecorator extends Decorator{public SpecificDecorator(Sourceable source) {super(source);}@Overridepublic void method() {System.out.println("----before decorator!----");super.method();System.out.println("----after decorator!----");}
}

测试类 Main

public class Main {public static void main(String[] args) {Sourceable source = new Source();Sourceable obj = new SpecificDecorator(source);obj.method();}
}

案例 2

需求 :

  • 给一个蛋糕类 添加 芒果 和葡萄的 装饰效果

抽象蛋糕类 Cake

public abstract class Cake {public abstract String getCakeMsg();public abstract BigDecimal getPrice();
}

普通蛋糕的类 BaseCake

public class BaseCake extends Cake {@Overridepublic String getCakeMsg() {return "我是一个8英寸的普通蛋糕";}@Overridepublic BigDecimal getPrice() {return new BigDecimal("68");}
}

抽象装饰器类 CakeDecorator

public abstract class CakeDecorator extends Cake{private Cake cake;public CakeDecorator(Cake cake) {this.cake = cake;}@Overridepublic String getCakeMsg() {return this.cake.getCakeMsg();}@Overridepublic BigDecimal getPrice() {return this.cake.getPrice();}
}

芒果蛋糕的装饰器类 CakeAddMangoDecorator

public class CakeAddMangoDecorator extends CakeDecorator {public CakeAddMangoDecorator(Cake cake) {super(cake);}@Overridepublic String getCakeMsg() {return super.getCakeMsg() + "+1个芒果";}@Overridepublic BigDecimal getPrice() {return super.getPrice().add(new BigDecimal("10"));}
}

葡萄蛋糕的装饰器类 CakeAddGrapeDecorator

public class CakeAddGrapeDecorator extends CakeDecorator {public CakeAddGrapeDecorator(Cake cake) {super(cake);}@Overridepublic String getCakeMsg() {return super.getCakeMsg() + "+1个葡萄";}@Overridepublic BigDecimal getPrice() {return super.getPrice().add(new BigDecimal("5"));}
}

测试类

public class TestCakeDecorator {public static void main(String[] args) {Cake cake = null;//普通蛋糕cake = new BaseCake();System.out.println(cake.getCakeMsg() + ",价格:" + cake.getPrice());//加一个芒果cake = new CakeAddMangoDecorator(cake);System.out.println(cake.getCakeMsg() + ",价格:" + cake.getPrice());//加一个葡萄cake = new CakeAddGrapeDecorator(cake);System.out.println(cake.getCakeMsg() + ",价格:" + cake.getPrice());//再加一个芒果cake = new CakeAddMangoDecorator(cake);System.out.println(cake.getCakeMsg() + ",价格:" + cake.getPrice());}
}

类图关系

Spring源码中装饰器模式

Spring 中用到的装饰器模式在类名上有两种表现:一种是类名中含有 Wrapper,另一种是类名中含有Decorator。

1 .Decorator例子

  • 在 Spring 中,TransactionAwareCacheDecorator
    类相当于装饰器模式中的抽象装饰角色,主要用来处理事务缓存,代码如下。
public class TransactionAwareCacheDecorator implements Cache {private final Cache targetCache;/*** Create a new TransactionAwareCache for the given target Cache.* @param targetCache the target Cache to decorate*/public TransactionAwareCacheDecorator(Cache targetCache) {Assert.notNull(targetCache, "Target Cache must not be null");this.targetCache = targetCache;}/*** Return the target Cache that this Cache should delegate to.*/public Cache getTargetCache() {return this.targetCache;}......
}

TransactionAwareCacheDecorator 就是对 Cache 的一个包装。

2 .Wrapper例子

  • Spring Session就是其中之一,Spring Session通过SessionRepositoryRequestWrapper继承ServletRequestWrapper,扩展了Request,并在SessionRepositoryFilter通过调用过滤链filterChain.doFilter(strategyRequest, strategyResponse);将装饰的Request传入下一流程,

具体请阅读以下类图的实现:

SessionRepositoryRequestWrapper覆盖了以下方法:

@Override
public boolean isRequestedSessionIdValid();@Override
public HttpSessionWrapper getSession(boolean create);@Override
public ServletContext getServletContext();@Override
public HttpSessionWrapper getSession();@Override
public String getRequestedSessionId();

总结

装饰者模式使用场景:

  1. 用于扩展一个类的功能或给一个类添加附加职责。
  2. 动态的给一个对象添加功能,这些功能可以再动态的撤销。

装饰者模式优点:

  1. 装饰者是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象 扩展功能,即插即用。
  2. 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
  3. 装饰者完全遵守开闭原则。

装饰者模式缺点:

  1. 会出现更多的代码,更多的类,增加程序复杂性。
  2. 动态装饰以及多层装饰时会更加复杂。

装饰器模式与代理模式异同

  1. 代理模式偏向于一个控制器,就是把被代理对象的控制权交给了代理对象,由代理对象决定被代理对象是否执行,如何执行
  2. 装饰模式偏向于一个和花瓶,只能在被装饰对象前后加入一点东西,并不会去阻止执行的

代理模式和装饰模式看代码差不多,实际上二者的着重点不同.

其实所谓装饰器,装饰器模式本质上,是对现有类对象的包裹,得到一个加强版的对象。

装饰器模式--Decorator相关推荐

  1. decorator java_装饰器模式-Decorator(Java实现)

    装饰器模式-Decorator(Java实现) 装饰器模式允许向一个现有的对象添加新的功能, 同时又不改变其结构. 其中 "现有对象"在本文中是StringDisplay类. 添加 ...

  2. c语言装饰,C/C++知识点之装饰器模式(Decorator) C++

    本文主要向大家介绍了 C/C++知识点之装饰器模式(Decorator) C++,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助.装饰器模式是比较常用的一种设计模式,Python中就 ...

  3. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  4. python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  5. 【Java设计模式系列】装饰器模式(Decorator Pattern)

    简介 一般有两种方式可以给一个类或对象新增行为: 继承 子类在拥有自身方法同时还拥有父类方法.但这种是静态的,用户无法控制增加行为的方式和时机. 关联 将一个类的对象嵌入另一个对象,由另一个对象决定是 ...

  6. 装饰器模式(Decorator)

    一.装饰者模式的定义: 装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 结构: 装饰器UML.png (1)抽象构件( ...

  7. 装饰器模式 decorator

    所有的说明和解释都在代码中有注释来标明 package mode.decorator;/*** * 这里定义一个接口,在接口中定义我们要执行的操作.* * 以后所有的装饰器以及我们要装饰的对象都要实现 ...

  8. 极速理解设计模式系列:23.装饰器模式(Decorator Pattern)

    五个角色:部件(Component).具体部件(ConcreteComponent).装饰抽象类(Decorator).具体装饰对象(ConcreteDecorator).客户端(Client) 部件 ...

  9. JAVA设计模式-装饰器模式(Decorator)

    装饰器模式(Decorator) 为了某个实现类在不修改原始类的基础上进行动态地覆盖或者增加方法 采用--------装饰器模式 实现类要保持与原有类的层级关系 装饰器模式是一种特殊的适配器模式 拿适 ...

最新文章

  1. 2021年春季学期-信号与系统-第三次作业参考答案-第九道题
  2. Spring 注解的作用
  3. 三、CSS重要的盒子模型知识总结(中篇)
  4. linux下使用sed批量替换关键词(带斜杠处理+kaggle路径批量替换)
  5. WordPress 常用数据库SQL查询语句大全
  6. drools 7.x定时器
  7. 如何看待夸克,酷狗概念版等简洁型软件?
  8. 使用sql语句向SDO_Geometry插入要素
  9. Linux Tomcat Cluster
  10. stm32的HAL库uart的注意点
  11. HTML问答页面模板,问答社区简单静态页面模板
  12. 压缩文件右击找不到Bandizip解压选项
  13. win10无法连接到这个网络_网络打印机连接正常但无法打印
  14. html5视频事件参数详细
  15. 二级域名的创建、简单配置域名解析
  16. 力扣杯2023春-个人赛、战队赛
  17. 什么都可以丢,唯独不能丢了你
  18. 程序员跳槽全攻略(路漫漫其修远兮)
  19. No.20-基础-渗透学习
  20. c语言标准库详解(十二):非局部跳转setjmp.h

热门文章

  1. python 六角形程序
  2. 那些触动人心的产品细节
  3. java实现控制台购书系统
  4. ibus拼音输入法输入不正确的解决办法
  5. 在centos8上部署docker-ce(参照官方网站上说明安装)
  6. python execjs库_python3调用js的库之execjs
  7. c语言语法词法 语义,转:编译原理之词法分析、语法分析、语义分析
  8. 从五种小球中任取三种,有多少种取法
  9. 编程语言用C语言来看“流星雨”,听说向流星许愿就会有好运气
  10. Ubuntu18.04开机切换用户登录设置