[01][01][09] 装饰器模式详解

1. 定义

装饰器模式是指在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)

2. 适用场景

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

3. 代码实现

一个小伙在上班路上看到一个卖煎饼的摊位,过去买个煎饼,需要加鸡蛋和香肠

当前的代码智能支持加鸡蛋, 火腿,如果还想加生菜或其他的,只需要增加对应的装饰器就可以了,不需要对原有代码做修改

3.1 基础抽象类

/**
 * 煎饼抽象类
 */
public abstract class BatterCake {
    /**
     * 煎饼信息
     * @return
     */
    protected abstract String getMsg();

    /**
     * 煎饼价格
     * @return
     */
    protected abstract int getPrice();
}

3.2 基础对象

package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;

/**
 * 普通煎饼
 */
public class BaseBatterCake extends BatterCake{
    /**
     * 煎饼信息
     * @return
     */
    protected String getMsg() {
        return "煎饼";
    }

    /**
     * 煎饼价格
     * @return
     */
    protected int getPrice() {
        return 5;
    }
}

3.3 装饰器

package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;

/**
 * 普通煎饼装饰器
 */
public abstract class BatterCakeDecorator extends BatterCake{

    private BatterCake batterCake;

    public BatterCakeDecorator(BatterCake batterCake) {
        this.batterCake = batterCake;
    }

    /**
     * 煎饼信息
     * @return
     */
    protected String getMsg() {
        return this.batterCake.getMsg();
    }

    /**
     * 煎饼价格
     * @return
     */
    protected int getPrice() {
        return this.batterCake.getPrice();
    }
}
package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;

/**
 * 加鸡蛋装饰器
 */
public class EggDecorator extends BatterCakeDecorator{

    public EggDecorator(BatterCake batterCake) {
        super(batterCake);
    }

    @Override
    protected String getMsg() {
        return super.getMsg() + "+一个鸡蛋";
    }

    @Override
    protected int getPrice() {
        return super.getPrice() + 1;
    }
}
package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;

/**
 * 加香肠装饰器
 */
public class SausageDecorator extends BatterCakeDecorator{

    public SausageDecorator(BatterCake batterCake) {
        super(batterCake);
    }

    @Override
    protected String getMsg() {
        return super.getMsg() + "+一根香肠";
    }

    @Override
    protected int getPrice() {
        return super.getPrice() + 2;
    }
}

3.4 测试类

package com.zhunongyun.toalibaba.designpatterns.decorator.battercake;

public class BatterCakeTest {
    public static void main(String[] args) {

        //在路边摊跟老板说买一个煎饼
        BatterCake batterCake = new BaseBatterCake();

        //煎饼有点小,跟老板说加一个鸡蛋
        batterCake = new EggDecorator(batterCake);

        //想要两个鸡蛋,跟老板说再加一个鸡蛋
        batterCake = new EggDecorator(batterCake);

        //肚子很饿想吃香肠, 跟老板说再加根香肠
        batterCake = new SausageDecorator(batterCake);

        //煎饼制作完成,买单
        System.out.println(batterCake.getMsg() + ", 价格:" + batterCake.getPrice());
    }
}

4. 源码分析

4.1 java.io中IO流

IO流总结起来就是大桶套小桶

public class FilterInputStream extends InputStream {
    .....

    protected FilterInputStream(InputStream in) {
        this.in = in;
    }
}
public class BufferedInputStream extends FilterInputStream {
    public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }
}

4.2 Spring中TransactionAwareCacheDecorator

public class TransactionAwareCacheDecorator implements Cache {
    private final Cache targetCache;

    public TransactionAwareCacheDecorator(Cache targetCache) {
        Assert.notNull(targetCache, "Target Cache must not be null");
        this.targetCache = targetCache;
    }
}

5. 装饰器模式与适配器模式对比

对比项 装饰器模式 适配器模式
形式 是一种非常特别的适配器模式 没有层级关系,装饰器模式有层级关系
定义 装饰器与被装饰这都要实现同一个接口,主要目的是为了扩展之后依旧保留OOP关系 适配器和被适配者没有必然联系,通常是采用继承或代理的形式进行包装
关系 满足is-a关系 满足has-a的关系
功能 注重覆盖,扩展 注重兼容,转换
设计 前置考虑 后置考虑
发布了29 篇原创文章 · 获赞 10 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/csharpqiuqiu/article/details/100057212