Skip to content

Latest commit

 

History

History
98 lines (74 loc) · 2.57 KB

装饰者.md

File metadata and controls

98 lines (74 loc) · 2.57 KB

装饰者 Decorator

重点等级::star::star::star::star::star:

动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
装饰者模式中装饰者和被装饰者具有相同的超类,在这利用继承达到了“类型匹配”,而不是利用继承获得“行为”。
装饰者和被装饰者拥有同一超类。装饰者实现同一超类的接口并持有被装饰者。

场景

  • 在不影响其他对象的情况下,动态地、透明地向各个对象添加职责

JDK及各大框架源码中的案例

  • JAVA IO java.io.InputStream, java.io.OutputStream, java.io.Reader 、java.io.Writer
  • java.util.Collections#synchronizedXXX()
  • java.util.Collections#unmodifiableXXX()
  • java.util.Collections#checkedXXX()
  • Spring-web 对 ServletRequest 使用 ServletRequestWrapper 进行包装装饰
  • Spring Security oauth2
    org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter  //被装饰者
    org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter //装饰者

代码案例

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
var troll = new SimpleTroll();
troll.attack(); // The troll tries to grab you!
troll.fleeBattle(); // The troll shrieks in horror and runs away!

// 通过装饰器来更改加强 troll
var clubbedTroll = new ClubbedTroll(troll);
clubbedTroll.attack(); // The troll tries to grab you! The troll swings at you with a club!
clubbedTroll.fleeBattle(); // The troll shrieks in horror and runs away!