「这是我参与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());
}
}
复制代码
查看测试结果
分析
装饰者模式的目的也是为了扩展对象的功能,是继承的一个替代模式,可以动态的扩展一个实现类的功能,装饰类和被装饰类可以相互独立,不会耦合,灵活方便。
使用场景
- 需要给一个现有类添加职责,但是有不能采用生成子类的方式去扩充的时候,
- 当需要对于现有的一组基本功能进行组合,会产生非常多的功能的时候
- 当对象的功能要求可以动态的添加,或者说的动态的撤销
预告
下篇我们将分析组合模式,敬请期待
需要源码的可以关注公众号【温故知新之java】,更多干活与你分享。