装饰器模式--Decorator
Posted 高高for 循环
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器模式--Decorator相关的知识,希望对你有一定的参考价值。
装饰器模式
定义:
- 装饰者模式(Decorator Pattern)是指在不改变原有对象的基础之上,将一些新的功能动态的添加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。
组成:
案例 1:
需求:
- Sourceable是抽象构建角色
- Source类是具体的被装饰类
- Decorator抽象装饰者
- SpecificDecorator具体的装饰者
抽象构建角色 Sourceable
public interface Sourceable {
void method();
}
具体被装饰类 Source
public class Source implements Sourceable {
@Override
public 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;
}
@Override
public void method() {
source.method();
}
}
具体的装饰者 SpecificDecorator
public class SpecificDecorator extends Decorator{
public SpecificDecorator(Sourceable source) {
super(source);
}
@Override
public 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 {
@Override
public String getCakeMsg() {
return "我是一个8英寸的普通蛋糕";
}
@Override
public BigDecimal getPrice() {
return new BigDecimal("68");
}
}
抽象装饰器类 CakeDecorator
public abstract class CakeDecorator extends Cake{
private Cake cake;
public CakeDecorator(Cake cake) {
this.cake = cake;
}
@Override
public String getCakeMsg() {
return this.cake.getCakeMsg();
}
@Override
public BigDecimal getPrice() {
return this.cake.getPrice();
}
}
芒果蛋糕的装饰器类 CakeAddMangoDecorator
public class CakeAddMangoDecorator extends CakeDecorator {
public CakeAddMangoDecorator(Cake cake) {
super(cake);
}
@Override
public String getCakeMsg() {
return super.getCakeMsg() + "+1个芒果";
}
@Override
public BigDecimal getPrice() {
return super.getPrice().add(new BigDecimal("10"));
}
}
葡萄蛋糕的装饰器类 CakeAddGrapeDecorator
public class CakeAddGrapeDecorator extends CakeDecorator {
public CakeAddGrapeDecorator(Cake cake) {
super(cake);
}
@Override
public String getCakeMsg() {
return super.getCakeMsg() + "+1个葡萄";
}
@Override
public 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();
总结
装饰者模式使用场景:
- 用于扩展一个类的功能或给一个类添加附加职责。
- 动态的给一个对象添加功能,这些功能可以再动态的撤销。
装饰者模式优点:
- 装饰者是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象 扩展功能,即插即用。
- 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
- 装饰者完全遵守开闭原则。
装饰者模式缺点:
- 会出现更多的代码,更多的类,增加程序复杂性。
- 动态装饰以及多层装饰时会更加复杂。
装饰器模式与代理模式异同
- 代理模式偏向于一个控制器,就是把被代理对象的控制权交给了代理对象,由代理对象决定被代理对象是否执行,如何执行
- 装饰模式偏向于一个和花瓶,只能在被装饰对象前后加入一点东西,并不会去阻止执行的
代理模式和装饰模式看代码差不多,实际上二者的着重点不同.
其实所谓装饰器,装饰器模式本质上,是对现有类对象的包裹,得到一个加强版的对象。
以上是关于装饰器模式--Decorator的主要内容,如果未能解决你的问题,请参考以下文章