目录
一、定义
二、场景
三、例子
四、优缺点
优点:
缺点:
一、定义
在不改变已有对象结构的情况下,动态添加新的功能到对象上,是继承的一种替代方案。属于结构型模式。
二、场景
1.扩展一个类的功能,添加附加职责,但不改变原有结构。
2.给一个对象动态添加或删除功能。
3.无法使用子类进行扩展时,这有两种情况:一是功能的排列组合非常多,可能产生大量的子类;另一种是无法派生子类。
三、例子
刚好点了一杯瑞幸到了,就以此为例。
定义一个咖啡接口(抽象组件)
public interface Coffee {/*** 描述* @return*/String info();/*** 价格* @return*/double price();
}
创建一个拿铁(具体组件)
public class Latte implements Coffee {@Overridepublic String info() {return "生椰丝绒拿铁";}@Overridepublic double price() {return 21;}
}
然后创建一个咖啡装饰器(抽象装饰器)
public abstract class CoffeeDecorator implements Coffee {private Coffee coffee;public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic String info() {return this.coffee.info();}@Overridepublic double price() {return this.coffee.price();}
}
下面创建2个具体装饰器:加糖、加奶油
public class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}public String info() {return super.info() + " 加糖";}@Overridepublic double price() {return super.price() + 1;}
}
public class CreamDecorator extends CoffeeDecorator{public CreamDecorator(Coffee coffee) {super(coffee);}@Overridepublic String info() {return super.info() + " 加奶油";}@Overridepublic 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.增加代码复杂性,使维护更困难