美文网首页
设计模式(8) : 装饰器模式

设计模式(8) : 装饰器模式

作者: a_salt_fish | 来源:发表于2019-02-17 15:23 被阅读0次

定义:

  • 在不改变原有对象的基础之上, 将功能附加到对象上.

提供了比继承更有弹性的替代方案(扩展对象的功能)

类型:

  • 结构型

使用场景

装饰器模式实现普通煎饼, 加鸡蛋, 加火腿, 加辣条等任意组合的煎饼.

如果不考虑设计模式, 使用常规方法实现, 那我需要设计很多类, 如普通煎饼, 鸡蛋煎饼, 火腿煎饼, 鸡蛋火腿煎饼等等各种煎饼类, 当装饰对象较多时, 类的数量是不可想象的所以绝不可取.

  • 在这个例子中, 煎饼Battercake属于被装饰的对象, 火腿, 鸡蛋等属于装饰煎饼的装饰者Decorator, 经过火腿鸡蛋等装饰过的煎饼还是一个煎饼.
    定义一个顶层抽象类, 煎饼与煎饼的装饰器都实现这个抽象IBattercake
public interface IBattercake {
    /**
     * 名称
     * @return
     */
    String getName();
    /**
     * 价格
     */
    Integer getPrice();
}

煎饼

public class Battercake implements IBattercake{

    private Integer price;

    public Battercake(Integer price) {
        this.price = price;
    }

    @Override
    public String getName() {
        return "煎饼";
    }

    @Override
    public Integer getPrice() {
        return price;
    }
}

装饰器抽象类与实现类

public abstract class AbstractBattercakeDecorator implements IBattercake{

    protected IBattercake battercake;

    public AbstractBattercakeDecorator(IBattercake battercake) {
        this.battercake = battercake;
    }
}
public class EggBattercake extends AbstractBattercakeDecorator{

    public EggBattercake(IBattercake battercake) {
        super(battercake);
    }

    @Override
    public String getName() {
        return battercake.getName() + "加鸡蛋";
    }

    @Override
    public Integer getPrice() {
        return battercake.getPrice() + 1;
    }
}
public class SausageBattercake extends AbstractBattercakeDecorator{

    public SausageBattercake(IBattercake battercake) {
        super(battercake);
    }

    @Override
    public String getName() {
        return battercake.getName() + "加火腿";
    }

    @Override
    public Integer getPrice() {
        return battercake.getPrice() + 2;
    }
}

测试与输出

public class Test {
    public static void main(String[] args) {
        IBattercake battercake = new Battercake(5);
        battercake = new EggBattercake(battercake);
        System.out.println(battercake.getName() + ":" + battercake.getPrice());
        battercake = new EggBattercake(battercake);
        battercake = new SausageBattercake(battercake);
        System.out.println(battercake.getName() + ":" + battercake.getPrice());
    }
}

输出结果: 

煎饼加鸡蛋:6
煎饼加鸡蛋加鸡蛋加火腿:9

uml图


TIM图片20190217150811.png

coding

源码中的应用

java.io.Reader 是一个经典的装饰器模式的应用, 如Reader, BufferReader, FileReader三个类BufferReader, FileReader都实现了Reader, 使用

Reader reader = new FileReader("filepath");
        reader = new BufferedReader(reader);

得到了一个具有Buffer功能的FileReader,
类比煎饼的例子, Reader 相当于IBattercake,
FIleReader 相当于 Battercake被装饰者, BufferReader则是装饰对象 EggBattercake和SausageBattercake.

优点:

  • 继承的有力补充, 比继承灵活, 不改变对象的情况下给一个对象扩展功能
  • 通过不同装饰类实现不同的装饰效果

缺点:

  • 出现更多的代码, 更多的类

github源码

相关文章

网友评论

      本文标题:设计模式(8) : 装饰器模式

      本文链接:https://www.haomeiwen.com/subject/gxygeqtx.html