装饰器模式--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();

总结

装饰者模式使用场景:

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

装饰者模式优点:

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

装饰者模式缺点:

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

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

  1. 代理模式偏向于一个控制器,就是把被代理对象的控制权交给了代理对象,由代理对象决定被代理对象是否执行,如何执行
  2. 装饰模式偏向于一个和花瓶,只能在被装饰对象前后加入一点东西,并不会去阻止执行的
代理模式和装饰模式看代码差不多,实际上二者的着重点不同.
其实所谓装饰器,装饰器模式本质上,是对现有类对象的包裹,得到一个加强版的对象。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值