美文网首页
设计模式3:装饰模式

设计模式3:装饰模式

作者: akak18183 | 来源:发表于2017-05-05 11:43 被阅读0次

装饰模式(Decorator Pattern)能动态附加对象的功能,装饰器提供了比继承更为灵活的扩展方案。
这个模式是继承的一种代替方案。
一般而言,这个模式的底层是一个接口或者是抽象类。然后还需要装饰类来扩展该接口或者继承抽象类,并进行“聚合”操作。也就是说,装饰类是在原有的功能上附加额外的功能。
还是来看代码吧:

Troll接口,意思是怪物?巨魔?有三个函数。

/**
 * 
 * Interface for trolls
 *
 */
public interface Troll {

  void attack();

  int getAttackPower();

  void fleeBattle();

}

然后SimpleTroll类,使用Troll接口。

/**
 * 
 * SimpleTroll implements {@link Troll} interface directly.
 *
 */
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!");
  }
}

装饰类TrollDecorator,可以看到,它不仅是使用了Troll接口,自己还另外带一个,并把接口函数全都委托给另带的那个。

/**
 * TrollDecorator is a decorator for {@link Troll} objects. The calls to the {@link Troll} interface
 * are intercepted and decorated. Finally the calls are delegated to the decorated {@link Troll}
 * object.
 *
 */
public class TrollDecorator implements Troll {

  private Troll decorated;

  public TrollDecorator(Troll decorated) {
    this.decorated = decorated;
  }

  @Override
  public void attack() {
    decorated.attack();
  }

  @Override
  public int getAttackPower() {
    return decorated.getAttackPower();
  }

  @Override
  public void fleeBattle() {
    decorated.fleeBattle();
  }
}

一个具体的装饰实现,继承装饰类,调用超类的基础上再自己加入一些东西,而超类的实现也就是外带的Troll接口实现,这样就在原有Troll之外增加了功能。

/**
 * Decorator that adds a club for the troll
 */
public class ClubbedTroll extends TrollDecorator {

  private static final Logger LOGGER = LoggerFactory.getLogger(ClubbedTroll.class);

  public ClubbedTroll(Troll decorated) {
    super(decorated);
  }

  @Override
  public void attack() {
    super.attack();
    LOGGER.info("The troll swings at you with a club!");
  }

  @Override
  public int getAttackPower() {
    return super.getAttackPower() + 10;
  }
}

你也许会问:这不还是继承吗?确实用到了继承,但和单纯使用继承来扩展功能还是有很大区别的。区别是什么呢?就是运行时可以改变类的行为。

public static void main(String[] args) {

    // simple troll
    LOGGER.info("A simple looking troll approaches.");
    Troll troll = new SimpleTroll();
    troll.attack();
    troll.fleeBattle();
    LOGGER.info("Simple troll power {}.\n", troll.getAttackPower());

    // change the behavior of the simple troll by adding a decorator
    LOGGER.info("A troll with huge club surprises you.");
    Troll clubbed = new ClubbedTroll(troll);
    clubbed.attack();
    clubbed.fleeBattle();
    LOGGER.info("Clubbed troll power {}.\n", clubbed.getAttackPower());
  }
}

SimpleTroll就是普通的一个Troll,给它套上ClubbedTroll装饰,马上就有了ClubbedTroll的功能。以此类推,还可以加别的装饰。这又是和继承的另一个重要的区别:自由组合。
N个装饰者总共可以产生2^N个不同类,如果一个个继承的话……
当然,由于装饰者的特性,最好额外功能不要求特定的顺序,也就是说额外功能之间互不影响为最佳。

相关文章

网友评论

      本文标题:设计模式3:装饰模式

      本文链接:https://www.haomeiwen.com/subject/exbjtxtx.html