什么是装饰者模式?
定义:装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
设计原则
1.开闭原则,即对修改关闭,对扩展开放
2.多用组合,少用继承
以咖啡店售卖咖啡为例
咖啡是所有咖啡和咖啡调味品的基类
1 2 3 4 5 6 7 8 9
| public abstract class Coffee { protected String name; public String getName(){ return name; } public abstract double getPrice(); }
|
创建一个摩卡咖啡继承自该基类
1 2 3 4 5 6 7 8 9 10 11
| public class Mocha extends Coffee { public Mocha(){ name = "摩卡咖啡"; } @Override public double getPrice() { return 20; } }
|
再来一个调味品抽象类继承咖啡基类,该类是所有调味品的父类
1 2 3
| public abstract class Condiment extends Coffee { public abstract String getName(); }
|
具体的咖啡装饰者继承自调味品类(给咖啡加点糖)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Sugar extends Condiment { Coffee coffee; public Sugar(Coffee coffee){ this.coffee = coffee; } @Override public String getName() { return coffee.getName()+",加糖"; } @Override public double getPrice() { return 1+coffee.getPrice(); } }
|
再给咖啡加点奶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Milk extends Condiment { Coffee coffee; public Milk(Coffee coffee){ this.coffee = coffee; } @Override public String getName() { return coffee.getName()+",加牛奶"; } @Override public double getPrice() { return 2+coffee.getPrice(); } }
|
好了,我们来写一个测试类测试一下
1 2 3 4 5 6 7 8 9 10
| public class Test { public static void main(String[] args){ Coffee coffees = new Mocha(); System.out.println(coffees.getName()+"-价格-"+coffees.getPrice()); Sugar sugars = new Sugar(coffees); System.out.println(sugars.getName()+"-价格-"+sugars.getPrice()); Milk milks = new Milk(sugars); System.out.println(milks.getName()+"-价格-"+milks.getPrice()); } }
|
输出结果
摩卡咖啡-价格-20.0
摩卡咖啡,加糖-价格-21.0
摩卡咖啡,加糖,加牛奶-价格-23.0
总结
如果有再多一个装饰者我们只需要扩展一个类去继承自调味品类,然后去装饰咖啡就行了。同样的再多一个咖啡品种我们只需要去继承自咖啡的基类就行了。java的io实现也是装饰者模式,都是围绕着InputStream或者OutputStream两个基类去扩展的。