目录
一、定义
二、场景
三、例子
四、优缺点
优点:
缺点:
一、定义
在不改变已有对象结构的情况下,动态添加新的功能到对象上,是继承的一种替代方案。属于结构型模式。
二、场景
1.扩展一个类的功能,添加附加职责,但不改变原有结构。
2.给一个对象动态添加或删除功能。
3.无法使用子类进行扩展时,这有两种情况:一是功能的排列组合非常多,可能产生大量的子类;另一种是无法派生子类。
三、例子
刚好点了一杯瑞幸到了,就以此为例。
定义一个咖啡接口(抽象组件)
public interface Coffee {
/**
* 描述
* @return
*/
String info();
/**
* 价格
* @return
*/
double price();
}
创建一个拿铁(具体组件)
public class Latte implements Coffee {
@Override
public String info() {
return "生椰丝绒拿铁";
}
@Override
public double price() {
return 21;
}
}
然后创建一个咖啡装饰器(抽象装饰器)
public abstract class CoffeeDecorator implements Coffee {
private Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String info() {
return this.coffee.info();
}
@Override
public double price() {
return this.coffee.price();
}
}
下面创建2个具体装饰器:加糖、加奶油
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
public String info() {
return super.info() + " 加糖";
}
@Override
public double price() {
return super.price() + 1;
}
}
public class CreamDecorator extends CoffeeDecorator{
public CreamDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String info() {
return super.info() + " 加奶油";
}
@Override
public double price() {
return super.price() + 3;
}
}
好了,下面用一个测试类测试一下
public class Test {
public static void main(String[] args) {
Coffee coffee = new Latte();
Coffee sugarCoffee = new SugarDecorator(coffee);
Coffee creamCoffee = new CreamDecorator(sugarCoffee);
System.out.println(creamCoffee.info() + ": " + creamCoffee.price());
}
}
// 输出如下
// 生椰丝绒拿铁 加糖 加奶油: 25.0
看下类图:
四、优缺点
优点:
1.动态扩展,比继承灵活
2.装饰类之间不同的排列组合实现不同的功能,可避免子类爆炸性增长
3.符合开闭原则
缺点:
1.增加程序复杂性,对程序设计人员有着更高的要求
2.增加代码复杂性,使维护更困难