10-装饰者模式

装饰者模式

装饰者模式的应用场景

​ **装饰者模式(Decorator Pattern)是指在不改变原有对象的基础上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。**装饰者模式在我们生活中应用也比较多,比如给煎饼加鸡蛋;给蛋糕加上一些水果;给房子装修等,为对象扩展一些额外的职责。装饰者在代码程序中适用于以下场景:

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

来看一个这样的场景,上班族白领其实大多有睡懒觉的习惯,每天早上上班都是踩点,于是很多小伙伴为了多赖一会儿床都不吃早餐。那么,也有些小伙伴可能在上班路上碰 到卖煎饼的路边摊,都会顺带一个到公司茶水间吃早餐。卖煎饼的大姐可以给你的煎饼 加鸡蛋,也可以加香肠。

首先创建一个建煎饼的抽象 Battercake 类:

package com.wenbin.design.pattern.decorator;

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

    protected abstract int getPrice();
}

创建一个基本的煎饼(或者叫基础套餐)BaseBattercake:

package com.wenbin.design.pattern.decorator;

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

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

然后,再创建一个扩展套餐的抽象装饰者 BattercakeDecotator 类:

package com.wenbin.design.pattern.decorator;

public abstract class BattercakeDecotator extends Battercake {

    // 静态代理
    private Battercake battercake;

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

    protected abstract void doSomething();

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

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

然后,创建鸡蛋装饰者 EggDecorator 类:

package com.wenbin.design.pattern.decorator;

public class EggDecorator extends BattercakeDecotator {

    public EggDecorator(Battercake battercake) {
        super(battercake);
    }

    @Override
    protected void doSomething() {

    }

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

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

创建香肠装饰者 SausageDecorator 类:

package com.wenbin.design.pattern.decorator;

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

    @Override
    protected void doSomething() {

    }

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

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

}

测试代码:

package com.wenbin.design.pattern.decorator;

public class BattercakeTest {
    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());

    }
}

运行结果:

image-20190919154554689

类图:

10-装饰者模式_第1张图片

装饰者模式和适配器模式对比

​ 装饰者和适配器模式都是包装模式(Wrapper Pattern),装饰者也是一种特殊的代理默哀是。

装饰者模式 适配器模式
形式 是一种非常特别的适配器模式 没有层级关系,装饰器模式有层级关系
定义 装饰者和被装饰者都实现了同一个接口,主要目的是为了扩展之后已经保留OOP关系 适配器和被适配者没有必然联系,通常是采用继承或代理的形式进行包装。
关系 满足is-a的关系 满足has-a的关系
功能 注重覆盖、扩展 注重兼容、转换
设计 前置考虑 后置考虑

装饰者模式的优缺点

优点:

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

缺陷:

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

你可能感兴趣的:(10-装饰者模式)