装饰者模式
定义
在不改变原有对象的基础之上,将功能附加到对象上。提供了比继承更有弹性的替代方案(扩展原有对象功能)
为什么要使用装饰者模式
如下图:我们的纯豆浆,可以搭配红糖,变成红糖豆浆,也可以搭配红豆变成红豆豆浆,同时也可以红糖配红豆一起组成红糖红豆豆浆,那如果我们每次有一个新的配料加入,我们就写一个新的类,将会导致我们的类无限多,类爆炸了,这个时候装饰者模式起作用了。
装饰者模式的结构
- 抽象组件(Component):给出一个抽象接口,以规范准备接收附加责任的对象(本文例子中为Drink 饮品对象)
- 被装饰者(ConcreteComponent):抽象组件(Component)的具体实现,也就是我们要装饰的具体对象(本文例子中为Soya豆浆对象)
- 装饰者(Decorator)组件:持有抽象组件(Component)的实例引用,该类的职责就是为了装饰具体组件对象定义的基类(本文例子中为Decorator 装饰器对象)
- 具体装饰(ConcreteDecorator):负责给构建对象装饰附加功能(本文中例子,就是红豆装饰豆浆)
具体代码
抽象组件(Component) Drink 饮品
package com.bowen;public interface Drink {//抽象组件public String desc();public double money();}
被装饰者(ConcreteComponent) Soya 豆浆
package com.bowen;public class Soya implements Drink {//被装饰者@Overridepublic String desc() {return "纯豆浆";}@Overridepublic double money() {return 5;}}
装饰者(Decorator)组件 Decorator
package com.bowen;public abstract class Decorator implements Drink{//装饰器//1.抽象类//2.实现抽像组件接口//3.持有抽象接口引用//定义私有的饮品接口private Drink drink;public Decorator(Drink drink){this.drink = drink;}@Overridepublic String desc() {return this.drink.desc();}@Overridepublic double money() {return this.drink.money();}}
具体装饰(ConcreteDecorator) 这里是红豆
package com.bowen;public class RedBean extends Decorator {public RedBean(Drink drink){super(drink);}@Overridepublic String desc() {return super.desc() + "+红豆";}@Overridepublic double money() {return super.money() + 4.2;}}
测试代码
package com.bowen;public class Test {public static void main(String[] args) {Drink soya = new Soya();//新建豆浆Drink redbean = new RedBean(soya); //加入红豆,生产红豆豆浆System.out.println(redbean.desc());System.out.println(redbean.money());}}结果:纯豆浆+红豆9.2
优缺点
- 优点
- 提供比继承更好的灵活性,装饰是动态的,运行时可以修改,继承是静态的,编译期间已确定好。
- 通过使用不同的装饰类及他们的排列组合,可以创造出许多不同行为的组合。
- 缺点
- 容易产生许多小对象,大量的小对象占用内存
- 组合方式过多不好管理,容易出错

