装饰者模式
定义:
动态的将责任附加到对象上,想要扩展功能,装饰者提供有别于继承的另一种选择
要点:
装饰者和被装饰者对象拥有相同的超类型
可以用一个或多个装饰者包装一个对象
因为装饰者与被装饰者拥有相同的超类型,在任何需要被装饰者对象的场合,可以用装饰过的对象替代他
- 装饰者可以在被装饰者行为前面或者后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的
- 装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为
- 装饰模式的用意是保持接口并增加对象的职责
优点:
- Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
缺点:
这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
例:
package com.cn.gaoyan;
// 公共抽象接口
public abstract class Beverage {
String decription = "unknown";
public String getDescription(){
return decription;
}
public abstract double cost();
}
package com.cn.gaoyan;
//被装饰者实例
public class Espresso extends Beverage{
public Espresso(){
decription = "Espresso";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 1.99;
}
}
package com.cn.gaoyan;
//被装饰者实例
public class HouseBlend extends Beverage{
public HouseBlend(){
decription = "HouseBlend";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 2.69;
}
}
package com.cn.gaoyan;
//装饰者
public abstract class DecoratorBeverage extends Beverage{
//覆写getDescription()函数,目的就是将被装饰者的行为取代掉
public abstract String getDescription();
}
package com.cn.gaoyan;
//装饰者实例
public class Mocha extends DecoratorBeverage{
Beverage beverage = null;
public Mocha(Beverage beverage){
this.beverage = beverage;
decription = "Mocha";
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription() + "," + this.decription;
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.5 + beverage.cost();
}
}
package com.cn.gaoyan;
//装饰者实例
public class Milk extends DecoratorBeverage{
Beverage beverage = null;
public Milk(Beverage beverage){
this.beverage = beverage;
this.decription = "Milk";
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription() + "," + this.decription;
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.15 + beverage.cost();
}
}
package com.cn.gaoyan;
//main()
public class MainTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Beverage beverage1 = new Espresso();
beverage1 = new Mocha(beverage1);
beverage1 = new Milk(beverage1);
System.out.println(beverage1.getDescription());
System.out.println(beverage1.cost());
}
}