结构型模式——装饰者模式(二)

2019-05-22  本文已影响0人  最后的轻语_dd43

该项目源码地址:https://github.com/lastwhispers/code/tree/master/java-basic/design-pattern
(设计模式相关代码与笔记)

1. 定义

在不改变原有对象的基础之上,动态地给一个对象添加一些额外的职责。

2. 适用场景

例如:在java的I/O类中有很深刻的体现。

3. 类图与角色

装饰者模式类图

4. 相关设计模式

装饰者模式和代理模式

装饰者模式和适配器模式

5. 模式实例

背景:公司门口有一个小摊卖煎饼的,点了煎饼之后往往还可以在这个基础之上增加一些配料,例如煎蛋,火腿等等,每个配料的价格都不一样,不管你怎么配配料,最终价格是煎饼基础价加上每一种所选配料价格的总和。

5.1 V1版本

(1)相关类

有一个煎饼类:

public class Battercake {
    protected String getDesc() {
        return "煎饼";
    }
    protected int cost() {
        return 8;
    }
}

如果此时需要一个加鸡蛋的煎饼,只需要让煎饼加鸡蛋类继承煎饼类即可。

煎饼加鸡蛋类:

public class BattercakeWithEgg extends Battercake {
    @Override
    public String getDesc() {
        return super.getDesc()+"加一个鸡蛋";
    }

    @Override
    public int cost() {
        return super.cost()+1;
    }

}

如果此时需要一个加鸡蛋加香肠的煎饼,只需要让煎饼加鸡蛋加香肠类继承煎饼加鸡蛋类即可。

煎饼加鸡蛋加香肠类:

public class BattercakeWithEggSausage extends BattercakeWithEgg{
    @Override
    public String getDesc() {
        return super.getDesc()+"一个香肠";
    }

    @Override
    public int cost() {
        return super.cost()+2;
    }
}

(2)测试

public class Test {
    public static void main(String[]args){
        Battercake battercake = new Battercake();
        System.out.println(battercake.getDesc()+"销售价格:"+battercake.cost());

        BattercakeWithEgg battercakeWithEgg = new BattercakeWithEgg();
        System.out.println(battercakeWithEgg.getDesc()+"销售价格:"+battercakeWithEgg.cost());

        BattercakeWithEggSausage battercakeWithEggSausage = new BattercakeWithEggSausage();
        System.out.println(battercakeWithEggSausage.getDesc()+"销售价格:"+battercakeWithEggSausage.cost());

    }
}

测试结果:

测试结果

此时类图,单纯的继承结构:

类图

如果我们此时想要一个煎饼加两个鸡蛋,就需要重新继承煎饼类Battercake,生成一个“加两个鸡蛋的煎饼类”。加三个鸡蛋...以此类推,每加一种类型的煎饼就会多生成一个类。下面使用装饰者模式进行改造。

5.2 V2版本

现在,我们用装饰者模式来改写V1版本:

(1)相关类

Component 有一个抽象的煎饼类:

public abstract class ABattercake {
    protected abstract String getDesc();
    protected abstract int cost();
}

ConcreteComponent 煎饼类继承于上面的抽象兼饼类:

public class Battercate extends ABattercake {
    @Override
    protected String getDesc() {
        return "煎饼";
    }

    @Override
    protected int cost() {
        return 8;
    }
}

Decorator 我们让抽象的装饰者类继承抽象的实体:

public class AbstractDecorator extends ABattercake{
    private ABattercake aBattercake;

    public AbstractDecorator(ABattercake aBattercake) {
        this.aBattercake = aBattercake;
    }

    @Override
    protected String getDesc() {
        return aBattercake.getDesc();
    }

    @Override
    protected int cost() {
        return aBattercake.cost();
    }
}

ConcreteDectrator 煎饼添加鸡蛋的装饰类继承于抽象的装饰类:

public class EggDecorator extends AbstractDecorator{

    public EggDecorator(ABattercake aBattercake) {
        super(aBattercake);
    }

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

    @Override
    protected int cost() {
        return super.cost()+1;
    }
}

ConcreteDectrator 煎饼添加香肠的装饰类,继承于抽象的装饰类:

public class SausageDecorator extends AbstractDecorator{

    public SausageDecorator(ABattercake aBattercake) {
        super(aBattercake);
    }

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

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

(2)测试

public class Test {
    public static void main(String[]args){
        ABattercake aBattercake;
        aBattercake = new Battercate();
        aBattercake = new EggDecorator(aBattercake);
        aBattercake = new EggDecorator(aBattercake);
        aBattercake = new SausageDecorator(aBattercake);
        System.out.println(aBattercake.getDesc()+"价格为:"+aBattercake.cost());
    }
}

测试结果:

测试结果

此时不管想加多少个鸡蛋还是香肠,都可以很灵活的添加上。

此时的类图:

V2版本类图

6. 优缺点

优点:

缺点:

7. 扩展-JDK1.7以及框架源码中的装饰者模式

7.1 Java I/O

Reader与java.io.BufferedReader

Reader BufferedReader

Reader是被装饰者,BufferedReader是装饰者

InputStream与FilterInputStream

InputStream FilterInputStream

InputStream是被装饰者,FilterInputStream是装饰者

下面是InputStream相关类图的装饰者模式体现。

InputStream类结构

7.2 Spring

TransactionAwareCacheDecorator

Cache TransactionAwareCacheDecorator

7.3 Spring-session

org.springframework.session.web.http.SessionRepositoryFilter.SessionRepositoryRequestWrapper

7.4 Tomcat

javax.servlet.ServletRequestWrapper

ServletRequestWrapper

7.5 Mybatis

org.apache.ibatis.cache.Cache

org.apache.ibatis.cache.Cache
上一篇下一篇

猜你喜欢

热点阅读