Java装饰者模式的示例详解
作者:温故知新之java 时间:2022-03-30 07:26:22
定义
装饰者模式:在不改变原有对象的基础之上,动态的将功能附加到对象上,提供了继承更有弹性的替代方案,也体现了开闭原则
案例
需求
一个人去咖啡店点了一杯卡布奇诺,加了一份热牛奶
方案
定义咖啡基类
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());
}
}
查看测试结果
分析
装饰者模式的目的也是为了扩展对象的功能,是继承的一个替代模式,可以动态的扩展一个实现类的功能,装饰类和被装饰类可以相互独立,不会耦合,灵活方便。
使用场景
需要给一个现有类添加职责,但是有不能采用生成子类的方式去扩充的时候,
当需要对于现有的一组基本功能进行组合,会产生非常多的功能的时候
当对象的功能要求可以动态的添加,或者说的动态的撤销
知识点补充
装饰模式的定义和特点
在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。
就像我们做菜,需要用到调料,菜,刀,火等一系列抽象的组件来最终完成一道菜。
装饰模式的定义:
指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。就增加功能来说,装饰模式比生成子类更加灵活。
特点:
装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
装饰器模式完全遵守开闭原则
缺点
装饰器模式会增加许多子类,过度使用会增加程序得复杂性。
装饰模式的结构
装饰模式的结构一般包含以下几个角色
1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
2. 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
来源:https://juejin.cn/post/7068553669196644389