动态的给一个对象添加一些额外的职责,同时又不改变其原本的结构,作为原有类的包装,就增加功能来说,装饰模式比生成子类更为灵活。
原本对象:
/**
* 原本功能
*/
interface Component {
/**
* 原本功能
*/
void operation();
}
@Log4j2
class ConcreteComponent implements Component {
@Override
public void operation() {
log.info("具体功能的操作");
}
}
装饰对象:
@Data
abstract class AbstractDecorator implements Component {
private Component component;
@Override
public void operation() {
Optional.ofNullable(component).ifPresent(Component::operation);
}
}
@Log4j2
class ConcreteComponentDecorator extends AbstractDecorator {
@Override
public void operation() {
super.operation();
decorate();
}
private void decorate() {
log.info("装饰原本功能");
}
}
访问装饰对象:
Component component = new ConcreteComponent();
log.info("装饰前");
component.operation();
ConcreteComponentDecorator decorator = new ConcreteComponentDecorator();
decorator.setComponent(component);
log.info("装饰后");
decorator.operation();
结果:
16:12:08.267 [main] INFO com.learn.putc.designpatterns.structure.decorate.DecoratePattern - 装饰前
16:12:08.276 [main] INFO com.learn.putc.designpatterns.structure.decorate.ConcreteComponent - 具体功能的操作
16:12:08.281 [main] INFO com.learn.putc.designpatterns.structure.decorate.DecoratePattern - 装饰后
16:12:08.373 [main] INFO com.learn.putc.designpatterns.structure.decorate.ConcreteComponent - 具体功能的操作
16:12:08.373 [main] INFO com.learn.putc.designpatterns.structure.decorate.ConcreteComponentDecorator - 装饰原本功能
如果你不想在增加很多子类的情况下扩展功能,就可以考虑装饰模式,如果是多层继承用装饰模式来替代还是比较复杂,所以适合的场景才是用设计模式的前提。