適配器模式也稱(包裝器Wrapper)
定義:將一個類的接口轉換成用戶希望的另一個接口,使得原本由於接口不兼容而不能一起工作的那些類可以一起工作
注【這裏的接口,指的是方法】
結構型模式:是描述如何將類或者對象結合在一起形成更大的結構,分爲兩種
類結構型模式:只關心類的組合,一般只存在繼承和實現的關係
對象結構型模式:只關心類和對象的組合,通過關聯關係,在一個類定義另一個類的實例作爲成員對象,再調用所定義成員對象的方法
所以適配器模式分爲如下四種
a.缺省適配器
b.類適配器
c.對象適配器
d.雙向適配器
適配器中的角色:
目標(Target)
適配器(Adapter)
適配者(Adaptee)
一:缺省適配器
1.1 : 缺省適配器模式(Default Adapter Pattern):
當不需要實現一個接口所提供的所有方法時, 可先計一個抽象類實現該接口,
併爲接口中每個方法提供一個默認實現( 空方法) , 那麼該抽象類的子類可以選擇性地覆蓋父類的某些方法
來實現需求, 它適用於不想使用一個接口中的所有方法的情況, 又稱爲單接口適配器模式。
1.2: 在JDK類庫的事件處理包java.awt.event中廣泛使用了缺省適配器模式, 如MouseListener, MouseAdapter
/**
在Java語言中, 一般我們可以使用兩種方式來實現鼠標事件處理類,
一種是通過實現MouseListener接口,
另一種是通過繼承MouseAdapter適配器類
* @author wzj
* @ClassName Demo1
* @Date 2020年2月19日 下午2:02:29
*
*/
public class Demo1 implements MouseListener{
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
}
//這裏就是使用了缺省適配器模式,需要哪個方法,直接覆蓋就行
class Demo2 extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseMoved(MouseEvent e) {}
}
需求:
用適配器模式(Adapter)模擬新能源汽車的發動機。
分析:新能源汽車的發動機有電能發動機(Electric Motor)和光能發動機(Optical Motor)等,各種發動機的驅動方法不同,例如,電能發動機的驅動方法 electricDrive() 是用電能驅動,而光能發動機的驅動方法 opticalDrive() 是用光能驅動,它們是適配器模式中被訪問的適配者。
客戶端希望用統一的發動機驅動方法 drive() 訪問這兩種發動機,所以必須定義一個統一的目標接口 Motor,然後再定義電能適配器(Electric Adapter)和光能適配器(Optical Adapter)去適配這兩種發動機。
二:用類適配器模式實現(一般只存在繼承和實現的關係)
2.1目標角色
//目標
public interface Motor {
void drive();
}
2.2:適配器角色
//電能發動機適配器
public class ElectricMotorAdapter extends ElectricMotor implements Motor{
@Override
public void drive() {
super.electricDrive();
}
}
//光能發動機適配器
public class OpticalMotorAdapter extends OpticalMotor implements Motor{
@Override
public void drive() {
super.opticalDrive();
}
}
2.3:適配者
//電能發動機適配器
public class ElectricMotorAdapter extends ElectricMotor implements Motor{
@Override
public void drive() {
super.electricDrive();
}
}
//光能發動機適配器
public class OpticalMotorAdapter extends OpticalMotor implements Motor{
@Override
public void drive() {
super.opticalDrive();
}
}
2.4:客戶端測試代碼
public class Client {
public static void main(String[] args) {
Motor motor; //依賴倒轉原則
motor = new ElectricMotorAdapter();//可配置在配置文件中!
motor.drive();
}
}
UML類圖
三:用對象適配器模式實現(一般只存在關聯的關係)
目標角色 和 適配者角色不需要修改!
3.1:適配器
//電能發動機適配器
public class ElectricMotorAdapter implements Motor{
private ElectricMotor electricMotor;
public ElectricMotorAdapter() {
electricMotor = new ElectricMotor();
}
@Override
public void drive() {
electricMotor.electricDrive();
}
}
//光能發動機適配器
public class OpticalMotorAdapter implements Motor{
private OpticalMotor opticalMotor;
public OpticalMotorAdapter() {
opticalMotor = new OpticalMotor();
}
@Override
public void drive() {
opticalMotor.opticalDrive();
}
}
UML類圖:
在現實生活中,經常出現兩個對象因接口不兼容而不能在一起工作的實例,這時需要第三者進行適配。例如,講中文的人同講英文的人對話時需要一個翻譯,用直流電的筆記本電腦接交流電源時需要一個電源適配器,用計算機訪問照相機的 SD 內存卡時需要一個讀卡器等。
在軟件設計中也可能出現:需要開發的具有某種業務功能的組件在現有的組件庫中已經存在,但它們與當前系統的接口規範不兼容,如果重新開發這些組件成本又很高,這時用適配器模式能很好地解決這些問題。
應用場景:
- 以前開發的系統存在滿足新系統功能需求的類,但其接口同新系統的接口不一致。
- 使用第三方提供的組件,但組件接口定義和自己要求的接口定義不同。