简介
在不改变原有对象的基础上,新增加功能,该模式属于结构型。
适用场景
1、职责应该在运行时动态地添加(或删除)到对象中
2、扩展功能比较方便
优点
1、比继承灵活,是继承的有力补充,不改变原有对象的基础上扩展功能
2、通过不同的排列组合实现不同的效果
3、符合开闭原则
缺点
1、出现更多的类,增加复杂性
2、动态装饰使程序更复杂
代码示例
先看uml图
场景描述:咖啡制作,有些人喜欢原味,有些人喜欢加牛奶,有些人喜欢加点糖,为了满足不同人的不同喜好,使用装饰者再好不过了,可以根据不同的喜欢进行组合。
接着来看看具体的类:
咖啡接口
public interface Coffee {
int getCost();
String getDesc();
}
咖啡的实现类
public class CoffeeImpl implements Coffee {
public int getCost() {
return 10;
}
public String getDesc() {
return "原味咖啡";
}
}
装饰者父类
public class CoffeeDecorator implements Coffee {
private Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
public int getCost() {
return coffee.getCost();
}
public String getDesc() {
return coffee.getDesc();
}
}
加牛奶装饰者类
public class AddMilkDecorator extends CoffeeDecorator {
public AddMilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public int getCost() {
return super.getCost()+2;
}
@Override
public String getDesc() {
return super.getDesc()+" 加点牛奶";
}
}
加糖装饰者类
public class AddSprinklesDecorator extends CoffeeDecorator {
public AddSprinklesDecorator(Coffee coffee) {
super(coffee);
}
@Override
public int getCost() {
return super.getCost()+1;
}
@Override
public String getDesc() {
return super.getDesc()+" 加点糖";
}
}
测试类
public class DecoratorTest {
public static void main(String[] args) {
Coffee coffee = new CoffeeImpl();
coffee = new AddMilkDecorator(coffee);
coffee = new AddSprinklesDecorator(coffee);
System.out.println(coffee.getDesc()+"价格:"+coffee.getCost());
}
}
输出
原味咖啡 加点牛奶 加点糖价格:13
上面示例源码
源码分析
jdk中应用
在文件流中大量使用了装饰者模式,如
Spring中应用
TransactionAwareCacheDecorator
也是使用了装饰者模式
servlet中应用
mybatis中应用
部分UML图
本文为博主原创文章,未经博主允许不得转载。
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载