1 Star 0 Fork 1

wow / java-notes

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
装饰者模式.md 3.23 KB
一键复制 编辑 原始数据 按行查看 历史
wow 提交于 2020-09-01 19:25 . 设计模式

概念

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

使用场景

  1. 用于扩展一个类的功能或给一个类添加附加职责。

  2. 动态的给一个对象添加功能,这些功能可以再动态的撤销。

比如我们在买煎饼果子时,有时会加一个蛋或者香肠之类的,这时我们的装饰者模式就派上用场了

实现

煎饼抽象类

public abstract class Battercake {
    public abstract String getMsg();

    public abstract int getPrice();
}

煎饼基础实现 - 定义了基础的煎饼

public class BaseBattercake  extends Battercake {
    @Override
    public String getMsg(){
        return "煎饼";
    }

    @Override
    public int getPrice(){ return 5; }
}

煎饼装饰者抽象类 - 我们在其中将煎饼作为成员变量进行保存

public abstract class BattercakeDecorator extends Battercake {
    //静态代理, 委派
    private Battercake battercake;

    public BattercakeDecorator(Battercake battercake) {
        this.battercake = battercake;
    }

    protected abstract void doSomething();

    @Override
    public String getMsg() {
        return this.battercake.getMsg();
    }

    @Override
    public int getPrice() {
        return this.battercake.getPrice();
    }

}

鸡蛋装饰者 - 它获取父类返回值,并进行累加

public class EggDecorator extends BattercakeDecorator {
    public EggDecorator(Battercake battercake) {
        super(battercake);
    }

    @Override
    protected void doSomething() {}

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

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

香肠装饰者

public class SausageDecorator extends BattercakeDecorator {
    public SausageDecorator(Battercake battercake) {
        super(battercake);
    }

    @Override
    protected void doSomething() {
    }

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

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

测试 - 在该代码中,我们通过类的累加实现了对基类的修改

public static void main(String[] args) {
    Battercake battercake;
    //路边摊买一个煎饼
    battercake = new BaseBattercake();
    //煎饼有点小, 想再加一个鸡蛋
    battercake = new EggDecorator(battercake);
    //再加一个鸡蛋
    battercake = new EggDecorator(battercake);
    //很饿, 再加根香肠
    battercake = new SausageDecorator(battercake);
    //跟静态代理最大区别就是职责不同
    //静态代理不一定要满足 is-a 的关系
    //静态代理会做功能增强, 同一个职责变得不一样
    //装饰器更多考虑是扩展
    System.out.println(battercake.getMsg() + ",总价: " + battercake.getPrice());
}

输出

煎饼+1 个鸡蛋+1 个鸡蛋+1 根香肠,总价 9
其他
1
https://gitee.com/superwow/java-notes.git
git@gitee.com:superwow/java-notes.git
superwow
java-notes
java-notes
master

搜索帮助