設(shè)計(jì)模式8:適配器模式

適配器(Adapter)大家應(yīng)該都不會(huì)陌生,比如電源適配器。比如我的手機(jī)電源適配器,一邊插雙孔插頭,一邊可以插USB,這其實(shí)就是現(xiàn)實(shí)世界的適配器模式(Adapter DP)。說白了很簡單,就是適配接口。
適配器有兩種,類適配器和對(duì)象適配器。類適配器是通過繼承被適配者的接口,對(duì)象適配器則是通過組合來獲得被適配者的接口。由于Java不支持多個(gè)繼承,一般使用對(duì)象適配器不占用繼承,不過也不是說類適配器就不能用。

代碼:
戰(zhàn)艦接口:

/**
 * The interface expected by the client.<br>
 * A Battleship can fire and move.
 *
 */
public interface BattleShip {

  void fire();

  void move();

}

船長,駕駛戰(zhàn)艦運(yùn)動(dòng)和開火:

/**
 * The Captain uses {@link BattleShip} to fight. <br>
 * This is the client in the pattern.
 */
public class Captain implements BattleShip {

  private BattleShip battleship;

  public Captain() {

  }

  public Captain(BattleShip battleship) {
    this.battleship = battleship;
  }

  public void setBattleship(BattleShip battleship) {
    this.battleship = battleship;
  }

  @Override
  public void fire() {
    battleship.fire();
  }

  @Override
  public void move() {
    battleship.move();
  }

}

被適配者,漁船:

/**
 *
 * Device class (adaptee in the pattern). We want to reuse this class
 *
 */
public class FishingBoat {

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

  public void sail() {
    LOGGER.info("The Boat is moving to that place");
  }

  public void fish() {
    LOGGER.info("fishing ...");
  }

}

這里漁船是一個(gè)類而不是接口,不過漁船可以看成使用漁船接口的一個(gè)類,影響不大。
現(xiàn)在我們要做的就是把漁船適配給船長當(dāng)做戰(zhàn)艦。
那么需要一個(gè)適配器:

/**
 *
 * Adapter class. Adapts the interface of the device ({@link FishingBoat}) into {@link BattleShip}
 * interface expected by the client ({@link Captain}). <br>
 * In this case we added a new function fire to suit the interface. We are reusing the
 * {@link FishingBoat} without changing itself. The Adapter class can just map the functions of the
 * Adaptee or add, delete features of the Adaptee.
 *
 */
public class BattleFishingBoat implements BattleShip {

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

  private FishingBoat boat;

  public BattleFishingBoat() {
    boat = new FishingBoat();
  }

  @Override
  public void fire() {
    LOGGER.info("fire!");
  }

  @Override
  public void move() {
    boat.sail();
  }
}

這個(gè)適配器值得認(rèn)真研究。這是一個(gè)對(duì)象適配器,采用了戰(zhàn)艦接口,同時(shí)通過組合,有一個(gè)漁船類,適配器就可以用漁船的方法來實(shí)現(xiàn)戰(zhàn)艦的方法。
因?yàn)槭墙M合,所以漁船必須使用一個(gè)實(shí)例。假如之前改成漁船接口,這里照樣需要在一個(gè)地方傳入漁船接口的實(shí)現(xiàn)類,這樣才能調(diào)用漁船的方法。
假如是類適配器,就直接繼承漁船并實(shí)現(xiàn)戰(zhàn)艦接口,因?yàn)樽约阂呀?jīng)是漁船了,可以直接用自己的方法來實(shí)現(xiàn)戰(zhàn)艦方法,就不再贅述了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容