别名
包装器
目的
动态地向一个对象添加额外职责,装饰模式提供了相对子类更加灵活的添加功能方式。
解释
真实案例
在附近的山区里,居住着一个凶猛的巨怪,它通常赤手,有时也武装。巨怪是用装饰合适的武器装备来武装自己,而不会是创建一个新的武装巨怪
白话
装饰模式可以在运行时动态地用装饰类包装一个对象,以达到改变该对象的行为。
维基百科
修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。
编程案例
以上面的巨怪为例,首先我们有一个实现了troll
接口的SimpleTroll
类。
public interface Troll {
void attack();
int getAttackPower();
void fleeBattle();
}
public class SimpleTroll implements Troll {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleTroll.class);
@Override
public void attack() {
LOGGER.info("The troll tries to grab you!");
}
@Override
public int getAttackPower() {
return 10;
}
@Override
public void fleeBattle() {
LOGGER.info("The troll shrieks in horror and runs away!");
}
}
下一步,我们给巨怪一根棒球棒,我们用装饰模式动态地实现
public class ClubbedTroll implements Troll {
private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class);
private Troll decorated;
public ClubbedTroll(Troll decorated) {
this.decorated = decorated;
}
@Override
public void attack() {
decorated.attack();
LOGGER.info("The troll swings at you with a club!");
}
@Override
public int getAttackPower() {
return decorated.getAttackPower() + 10;
}
@Override
public void fleeBattle() {
decorated.fleeBattle();
}
}
巨怪实战
// simple troll
Troll troll = new SimpleTroll();
troll.attack(); // The troll tries to grab you!
troll.fleeBattle(); // The troll shrieks in horror and runs away!
// change the behavior of the simple troll by adding a decorator
troll = new ClubbedTroll(troll);
troll.attack(); // The troll tries to grab you! The troll swings at you with a club!
troll.fleeBattle(); // The troll shrieks in horror and runs away!
适用性
装饰器模式用于
- 在不影响其他对象的场景下,透明地、动态地向一个独立的对象新增职责
- 上述职责是可撤回的
- 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
网友评论