装饰者模式:动态地将责任附加到对象上。若要扩展对象,装饰者提供了比继承更有弹性的替代方案。
举例:有一家咖啡厅,主要饮料有咖啡,牛奶等。配料有糖,椰果等。每一款饮料都可以加入不限配料,但只有一款主饮。
此时,针对饮料有一个抽象类
- package com.zlh.decoretor;
- public abstract class Beverage {
- String description;
- abstract double cost();
- String getDescription() {
- return description;
- }
- }
咖啡,牛奶的实现如下:
- package com.zlh.decoretor;
- public class Milk extends Beverage{
- public Milk() {
- this.description = "milk";
- }
- public double cost() {
- return 1;
- }
- public String getDescription() {
- return description;
- }
- }
- package com.zlh.decoretor;
- public class Coffee extends Beverage {
- public Coffee() {
- this.description = "milk";
- }
- public double cost() {
- return 2;
- }
- public String getDescription() {
- return this.description;
- }
- }
为了实现装饰模式,每一款配料都有一个基本抽象类,此抽象类继承自beverage,但重写了getDescription方法,用于输出整个装饰中所有的主料和配料名称。
- package com.zlh.decoretor;
- public abstract class CondimentDecorator extends Beverage{
- @Override
- abstract String getDescription();
- }
在具体装饰类中,聚合了被装饰的饮料。如下:
- package com.zlh.decoretor;
- public class SugarMilk extends CondimentDecorator{
- private Beverage beverage;
- public SugarMilk(Beverage beverage) {
- this.description = "suger ";
- this.beverage = beverage;
- }
- public double cost() {
- return 0.5 + beverage.cost();
- }
- public String getDescription() {
- return this.description + beverage.description;
- }
- }
同样,更深层次的包装也可以这么实现:
- package com.zlh.decoretor;
- public class CoconutSugarMilk extends CondimentDecorator{
- private Beverage beverage;
- public CoconutSugarMilk(Beverage beverage) {
- this.description = "coconut ";
- this.beverage = beverage;
- }
- public double cost() {
- return 0.3 + beverage.cost();
- }
- public String getDescription() {
- return "cconut"+beverage.getDescription();
- }
- }
可以看出,无论装饰多少层,所有的实现,其实都是一样的。
以下是测试代码:
- package com.zlh.decoretor;
- public class TestDriver {
- public static void main(String[] args) {
- Beverage sugarMilk = new SugarMilk(new Milk());
- System.out.println(sugarMilk.getDescription());
- System.out.println(sugarMilk.cost());
- Beverage coconutSugarMilk = new CoconutSugarMilk(sugarMilk);
- System.out.println(coconutSugarMilk.getDescription());
- System.out.println(coconutSugarMilk.cost());
- }
- }
以上就是全部源码,装饰类的典型应用就是I/O中streamBuffer等。
转载于:https://blog.51cto.com/richardor/659568