結構型模式之適配器模式(1)

適配器模式也稱(包裝器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 內存卡時需要一個讀卡器等。

在軟件設計中也可能出現:需要開發的具有某種業務功能的組件在現有的組件庫中已經存在,但它們與當前系統的接口規範不兼容,如果重新開發這些組件成本又很高,這時用適配器模式能很好地解決這些問題。 

應用場景:

  • 以前開發的系統存在滿足新系統功能需求的類,但其接口同新系統的接口不一致。
  • 使用第三方提供的組件,但組件接口定義和自己要求的接口定義不同。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章