装饰者模式是对客户透明的方式,动态的给对象附加更多的功能和责任,就是不用创建更多的子类的情况下就可以将对象的功能进行扩展。
优点:避免了子类爆炸的问题,解决了对于一个产品功能动态扩展的问题,其UML类图如下所示
构成:
1、抽象构件(Component)
定义对象的接口,用来给对象增加新的功能
2、具体构件(ConcreteComponent)
定义具体的构件对象,实现了抽象构件中声明的方法,是被装饰的对象,也是给这个对象添加新的功能
3、抽象装饰器(Decorator)
抽象装饰器是抽象构件的子类,用于给具体构件增加新的功能,但是具体实现在其子类(ConcerateDecoratorA)中实现,一般一个装饰器一次只能装饰一个对象。
4、具体装饰器(ConceratorDecoratorA)
具体装饰器是抽象装饰器的子类,负责向构件添加新的功能。
举例:现在快餐店有汉堡、土司、鸡排等,每天都要根据客户下的订单来做,客户一般会下一个汉堡+热狗、汉堡+鸡蛋等这样的订单,因此为了避免子类爆炸要用装饰者模式
1、建立一个抽象构件表示汉堡、土司、鸡排等;
2、实现具体的构件
3、建立一个抽象的装饰器
4、建立具体的装饰器(鸡蛋、热狗、培根等附加物)
代码实现按序如下:
1、定义抽象的构件
public abstract class Breakfast {
public String description = "未知";
public String getDescription(){
return description;
}
public abstract double cost();
}
2、创建具体的构件
public class Ham extends Breakfast {
public Ham() {
description = "汉堡";
}
@Override
public double cost() {
return 15;
}
}
3、创建抽象的装饰器
public abstract class CondimentDecorator extends Breakfast {
//依赖于具体的构件
Breakfast breakfast;
//通过形参的方式传入进来
public CondimentDecorator(Breakfast breakfast) {
this.breakfast = breakfast;
}
@Override
public String getDescription(){
return breakfast.getDescription();
}
@Override
public double cost(){
return breakfast.cost();
}
}
4、创建具体的装饰器
public class egg extends CondimentDecorator {
public egg(Breakfast breakfast) {
super(breakfast);
}
@Override
public String getDescription(){
return super.getDescription() + "鸡蛋";
}
@Override
public double cost(){
return super.cost() + 2;
}
}
5、测试代码
public class Test {
public static void main(String[] args) {
Breakfast breakfast = new Ham();
String description = breakfast.getDescription();
System.out.println(description);
double cost = breakfast.cost();
System.out.println(cost);
System.out.println("-----------------------------");
Breakfast breakfast2 = new egg(breakfast);
String description2 = breakfast2.getDescription();
System.out.println(description2);
double cost2 = breakfast2.cost();
System.out.println(cost2);
}
}
结果如下:
汉堡
15.0
-----------------------------
汉堡鸡蛋
17.0