適配器(Adapter)大家應該都不會陌生,比如電源適配器。比如我的手機電源適配器,一邊插雙孔插頭,一邊可以插USB,這其實就是現實世界的適配器模式(Adapter DP)。說白了很簡單,就是適配接口。
適配器有兩種,類適配器和對象適配器。類適配器是通過繼承被適配者的接口,對象適配器則是通過組合來獲得被適配者的接口。由于Java不支持多個繼承,一般使用對象適配器不占用繼承,不過也不是說類適配器就不能用。
代碼:
戰艦接口:
/**
* The interface expected by the client.<br>
* A Battleship can fire and move.
*
*/
public interface BattleShip {
void fire();
void move();
}
船長,駕駛戰艦運動和開火:
/**
* 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 ...");
}
}
這里漁船是一個類而不是接口,不過漁船可以看成使用漁船接口的一個類,影響不大。
現在我們要做的就是把漁船適配給船長當做戰艦。
那么需要一個適配器:
/**
*
* 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();
}
}
這個適配器值得認真研究。這是一個對象適配器,采用了戰艦接口,同時通過組合,有一個漁船類,適配器就可以用漁船的方法來實現戰艦的方法。
因為是組合,所以漁船必須使用一個實例。假如之前改成漁船接口,這里照樣需要在一個地方傳入漁船接口的實現類,這樣才能調用漁船的方法。
假如是類適配器,就直接繼承漁船并實現戰艦接口,因為自己已經是漁船了,可以直接用自己的方法來實現戰艦方法,就不再贅述了。