定义:在不改变对象的基础上,附加新的功能
类型:结构型
应用场景
- 给一个类添加功能或者添加附属职责
- 动态的给一个对象添加功能。
优点
- 提供了比继承更有弹性的扩展功能的替代方案
- 继承的有力补充。
- 可以通过组合的形式动态的去装饰原有的类。更灵活的扩展功能
- 符合开闭原则
缺点
- 出现更多的类、更多的代码增加了程序的复杂性
- 动态装饰、多层装饰将会更加复杂
替代方案扩展知识
- 将基本稳定的属性封装到对象(数据库)里,然后将功能封装到对应不同的service类里,将具有的功能列表放到数据库的配置表。 这样将复杂的组装变换成对db的增删改、将功能的配置与功能解耦。
源码应用的场景
- java IO包
public
class FilterInputStream extends InputStream {
/**
* The input stream to be filtered.
*/
protected volatile InputStream in;
protected FilterInputStream(InputStream in) {
this.in = in;
}
}
public class FileInputStream extends InputStream
{
}
- mybatis的cache使用了装饰者模式
demo
UML
目录结构
AbstractPancake
package structual.decorator;
public abstract class AbstractPancake {
protected abstract String getDesc();
protected abstract int getPrice();
}
Pancake
package structual.decorator;
public class Pancake extends AbstractPancake {
@Override
protected String getDesc() {
return "玉米面的煎饼";
}
@Override
protected int getPrice() {
return 5;
}
}
AbstractDecorator
package structual.decorator;
public class AbstractDecorator extends AbstractPancake {
private AbstractPancake abstractPancake;
public AbstractDecorator(AbstractPancake abstractPancake) {
this.abstractPancake = abstractPancake;
}
@Override
protected String getDesc() {
return this.abstractPancake.getDesc();
}
@Override
protected int getPrice() {
return this.abstractPancake.getPrice();
}
}
EggDecorator
package structual.decorator;
public class EggDecorator extends AbstractDecorator {
public EggDecorator(AbstractPancake abstractPancake) {
super(abstractPancake);
}
@Override
protected String getDesc() {
return super.getDesc()+",加蛋";
}
@Override
protected int getPrice() {
return super.getPrice()+1;
}
}
SausageDecorator
package structual.decorator;
public class SausageDecorator extends AbstractDecorator {
public SausageDecorator(AbstractPancake abstractPancake) {
super(abstractPancake);
}
@Override
protected String getDesc() {
return super.getDesc()+",加香肠";
}
@Override
protected int getPrice() {
return super.getPrice()+2;
}
}
PancakeTest
package structual.decorator;
import org.junit.Test;
import static org.junit.Assert.*;
public class PancakeTest {
@Test
public void test(){
AbstractPancake pancake = new Pancake();
AbstractDecorator eggDecorator = new EggDecorator(pancake);
AbstractDecorator sausageDecorator = new SausageDecorator(eggDecorator);
System.out.println(sausageDecorator.getDesc()+":"+sausageDecorator.getPrice());
}
}