装饰器模式
更多设计模式小故事案例代码详解 >><< 设计模式,如此简单~
所属类型: 结构型
标签:
- Java
- Gang Of Four
- Difficulty-Beginner(入门级难度)
注:
什么是 GOF(四人帮,全拼 Gang of Four)?
在 1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。 四位作者合称 GOF(四人帮,全拼 Gang of Four)。他们所提出 对接口编程而不是对实现编程。 优先使用对象组合而不是继承。
别名
Wrapper(包装器) (适配器模式(Adapter Pattern)和装饰器模式(Decorator Pattern)的统称)
意图
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
释义
小故事案例
有一只怪兽,它平时的时候赤手空拳,攻击力有10.如果要攻击力到20需要一把武器,现在我们不需要重新找一个有武器的怪兽,只需要给现在的怪兽增加10攻击就可以了.
简单来说
装饰器模式可以在装饰器类中通过装饰,来动态的改变被装饰类的行为
维基百科这样说
在面向对象编程中,装饰器模式是一种设计模式,它允许静态或动态地将行为添加到单个对象,而不影响来自同一类的其他对象的行为。装饰模式对于坚持单一的责任原则通常是有用的,因为它允许功能在具有独特关注区域的类之间进行划分。
代码详解
我们有一个小怪兽接口和一个简单的小怪兽
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 trollTroll 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 decoratortroll = 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!复制代码
适用契机
- 扩展一个类的功能。
- 动态增加功能,动态撤销。
- 通过子类的扩展是不切实际的。有时,大量的独立扩展是可能的,并且会产生大量子类来支持每个组合。或者类定义可以隐藏或不可用于子类化。
相关教程
实际应用
- , , and