转载:http://blog.csdn.net/yanbober/article/details/45395747
一、装饰者模式的定义
装饰者( Decorator )模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。
二、模式中包含的角色及其职责
- 抽象组件角色: 一个抽象接口,是被装饰类和装饰类的父接口。
- 具体组件角色:为抽象组件的实现类。
- 抽象装饰角色:包含一个组件的引用,并定义了与抽象组件一致的接口。
- 具体装饰角色:为抽象装饰角色的实现类。负责具体的装饰。
三、装饰者模式的特点
(1)装饰者和被装饰者有相同的接口(或有相同的父类)。
(2)装饰者保存了一个被装饰者的引用。
(3)装饰者接受所有客户端的请求,并且这些请求最终都会返回给被装饰者。
(4)在运行时动态地为对象添加属性,不必改变对象的结构。
四、Demo
抽象组件角色
/** * @author yangshijing * @desc Component * @created 2018/3/21 0021 */ public abstract class Person { String description = "Unkonwn"; public String getDescription() { return description; } //计算花费 public abstract double cost(); }
具体组件角色
/** * @author yangshijing * @desc ConcreteComponent * @created 2018/3/21 0021 */ public class Teenager extends Person { public Teenager() { description = "Shopping List:"; } @Override public double cost() { return 0; } }
抽象装饰角色
/** * @author yangshijing * @desc Decorator * @created 2018/3/21 0021 */ public abstract class ClothingDecorator extends Person { @Override public abstract String getDescription(); }
具体装饰角色
/** * @author yangshijing * @desc ConcreteDecorator * @created 2018/3/21 0021 */ public class Shirt extends ClothingDecorator { /** * 用实例变量保存Person的引用 */ Person person; public Shirt(Person person) { this.person = person; } @Override public String getDescription() { return person.getDescription() + "a shirt "; } @Override public double cost() { //实现了cost()方法,并调用了person的cost()方法,目的是获得所有累加值 return 100 + person.cost(); } }
/** * @author yangshijing * @desc ConcreteDecorator * @created 2018/3/21 0021 */ public class Casquette extends ClothingDecorator { Person person; public Casquette(Person person) { this.person = person; } @Override public String getDescription() { //鸭舌帽 return person.getDescription() + "a casquette "; } @Override public double cost() { return 75 + person.cost(); } }
五、测试方法及结果
/** * @author yangshijing * @desc 测试方法 * @created 2018/3/21 0021 */ public class Shopping { public static void main(String[] args) { Person person = new Teenager(); person = new Shirt(person); person = new Casquette(person); System.out.println(person.getDescription() + " ¥ " +person.cost()); } }
控制台输出
Shopping List:a shirt a casquette ¥ 175.0