你不知道如何扩展对象的功能?装饰者模式可以了解一下

「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战

定义

装饰者模式:在不改变原有对象的基础之上,动态的将功能附加到对象上,提供了继承更有弹性的替代方案,也体现了开闭原则

案例

需求

一个人去咖啡店点了一杯卡布奇诺,加了一份热牛奶

方案

定义咖啡基类

public abstract class Coffee {
    private String desc;

    private float price;

    public abstract float cost();

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }
}
复制代码

定义卡布奇诺咖啡类,继承咖啡基类

public class Cappuccino extends Coffee{
    public Cappuccino(){
        setDesc("点了一杯卡布奇诺");
        setPrice(100);
    }

    @Override
    public float cost() {
        System.out.println("当前价格为:" + super.getPrice());
        return super.getPrice();
    }
}
复制代码

定义装饰者类

public class Decorator extends Coffee{

    private Coffee coffee;

    public Decorator(Coffee coffee){
        this.coffee = coffee;
    }

    @Override
    public float cost() {
        return super.getPrice() + this.coffee.cost();
    }

    @Override
    public String getDesc() {
        return super.getDesc() + coffee.cost();
    }
}
复制代码

定义热牛奶类

public class HotMilk extends Decorator {
    public HotMilk(Coffee coffee){
        super(coffee);
        setPrice(200);
        setDesc("点了一杯热牛奶");
    }
}
复制代码

定义测试类

public class Test {
    public static void main(String[] args) {
        // 点了一杯卡布奇诺,还加了一份热牛奶
        Coffee coffee = new Cappuccino();
        System.out.println(coffee.getDesc());
        //System.out.println(coffee.getPrice());
        System.out.println(coffee.cost());;

        HotMilk hotMilk = new HotMilk(coffee);
        System.out.println(hotMilk.getDesc());
        //System.out.println(hotMilk.getPrice());
        System.out.println(hotMilk.cost());
    }
}
复制代码

查看测试结果

image.png

分析

装饰者模式的目的也是为了扩展对象的功能,是继承的一个替代模式,可以动态的扩展一个实现类的功能,装饰类和被装饰类可以相互独立,不会耦合,灵活方便。

使用场景

  • 需要给一个现有类添加职责,但是有不能采用生成子类的方式去扩充的时候,
  • 当需要对于现有的一组基本功能进行组合,会产生非常多的功能的时候
  • 当对象的功能要求可以动态的添加,或者说的动态的撤销

预告

下篇我们将分析组合模式,敬请期待

需要源码的可以关注公众号【温故知新之java】,更多干活与你分享。

Guess you like

Origin juejin.im/post/7068553669196644389