適配器模式

現實生活中的適配器例子html

泰國插座用的是兩孔的(歐標),能夠買個多功能轉換插頭 (適配器) ,這樣就能夠
使用了。java

基本介紹
1) 適配器模式( Adapter Pattern )將某個類的接口轉換成客戶端指望的另外一個接口表示,主的目的是兼容性,讓本來因接口不匹配不能一塊兒工做的兩個類能夠協同工做。其別名爲包裝器(Wrapper)
2) 適配器模式屬於結構型模式
3) 主要分爲三類:類適配器模式、對象適配器模式、接口適配器模式設計模式

工做原理
1) 適配器模式:將一個類的接口轉換成另外一種接口.讓本來接口不兼容的類能夠兼容
2) 從用戶的角度看不到被適配者,是解耦的
3) 用戶調用適配器轉化出來的目標接口方法,適配器再調用被適配者的相關接口方法
4) 用戶收到反饋結果,感受只是和目標接口交互,如圖(關鍵詞:src,adapter,dst )app

類適配器模式
基本介紹:
Adapter 類,經過繼承 src 類,實現 dst 類接口,完成 src->dst 的適配。
(Adapter extends src implements dst )
應用實例:
1) 應用實例說明
以生活中充電器的例子來說解適配器,充電器自己至關於Adapter,220V交流電至關於src (即被適配者),咱們的目dst(即 目標)是5V直流電
2) 思路分析(類圖)框架

3) 代碼實現ide

//被適配的類
public class Voltage220V {
	//輸出220V的電壓
	public int output220V() {
		int src = 220;
		System.out.println("電壓=" + src + "伏");
		return src;
	}
}
//適配接口
public interface IVoltage5V {
	public int output5V();
}
//適配器類
public class VoltageAdapter extends Voltage220V implements IVoltage5V {
	@Override
	public int output5V() {
		//獲取到220V電壓
		int srcV = output220V();
		int dstV = srcV / 44 ; //轉成 5v
		return dstV;
	}
}
public class Phone {
	//充電
	public void charging(IVoltage5V iVoltage5V) {
		if(iVoltage5V.output5V() == 5) {
			System.out.println("電壓爲5V, 能夠充電~~");
		} else if (iVoltage5V.output5V() > 5) {
			System.out.println("電壓大於5V, 不能充電~~");
		}
	}
}
public class Client {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(" === 類適配器模式 ====");
		Phone phone = new Phone();
		phone.charging(new VoltageAdapter());
	}
}

  

類適配器模式注意事項和細節
1) Java 是單繼承機制,因此類適配器須要 繼承 src 類這一點算是一個缺點, 由於這要求 dst 必須是接口,有必定侷限性;
2) src 類的方法在 Adapter 中都會暴露出來,也增長了使用的成本。
3) 因爲其繼承了 src 類,因此它能夠根據需求重寫 src 類的方法,使得 Adapter 的靈活性加強了。源碼分析

對象適配器模式
基本介紹:
1) 基本思路 和 類的適配器模式 相同,只是將 Adapter 類做修改,不是繼承src類,而是持有src類的實例,以解決兼容性的問題。 即:持有 src類,實現 dst 類接口,完成src->dst的適配
2) 根據「合成複用原則」,在系統中儘可能使用 關聯關係 來替代 繼承關係。
3) 對象適配器模式是適配器模式經常使用的一種動畫

應用實例:
1) 應用實例說明
以生活中充電器的例子來說解適配器,充電器自己至關於Adapter,220V交流電至關於src (即被適配者),咱們的目dst(即目標)是5V直流電,使用對象適配器模式完成。
2) 思路分析(類圖):只需修改適配器便可, 以下:this

3)代碼實現spa

//被適配的類
public class Voltage220V {
	//輸出220V的電壓,不變
	public int output220V() {
		int src = 220;
		System.out.println("電壓=" + src + "伏");
		return src;
	}
}
//適配接口
public interface IVoltage5V {
	public int output5V();
}
//適配器類
public class VoltageAdapter  implements IVoltage5V {
	private Voltage220V voltage220V; // 關聯關係-聚合
	//經過構造器,傳入一個 Voltage220V 實例
	public VoltageAdapter(Voltage220V voltage220v) {
		this.voltage220V = voltage220v;
	}
	@Override
	public int output5V() {	
		int dst = 0;
		if(null != voltage220V) {
			int src = voltage220V.output220V();//獲取220V 電壓
			System.out.println("使用對象適配器,進行適配~~");
			dst = src / 44;
			System.out.println("適配完成,輸出的電壓爲=" + dst);
		}	
		return dst;	
	}
}
public class Phone {
	//充電
	public void charging(IVoltage5V iVoltage5V) {
		if(iVoltage5V.output5V() == 5) {
			System.out.println("電壓爲5V, 能夠充電~~");
		} else if (iVoltage5V.output5V() > 5) {
			System.out.println("電壓大於5V, 不能充電~~");
		}
	}
}
public class Client {
	public static void main(String[] args) {
		System.out.println(" === 對象適配器模式 ====");
		Phone phone = new Phone();
		phone.charging(new VoltageAdapter(new Voltage220V()));
	}
}

對象適配器模式注意事項和細節
1) 對象適配器和類適配器其實算是同一種思想,只不過實現方式不一樣。根據合成複用原則,使用組合替代繼承, 因此它解決了類適配器必須繼承src的侷限性問題,也再也不要求 dst 必須是接口。
2) 使用成本更低,更靈活。

接口適配器模式
基本介紹:
1) 一些書籍稱爲:適配器模式(Default Adapter Pattern)或缺省適配器模式。
2) 當不須要所有實現接口提供的方法時,可先設計一個抽象類實現接口,併爲該接口中每一個方法提供一個默認實現(空方法),那麼該抽象類的子類可有選擇地覆蓋父類的某些方法來實現需求
3) 適用於一個接口不想使用其全部的方法的狀況。

應用實例:
1) Android中的屬性動畫 ValueAnimator 類能夠經過 addListener ( AnimatorListener listener )方法添加監聽器, 那麼常規寫法以下:

ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
valueAnimator.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
    }
    @Override
    public void onAnimationEnd(Animator animation) {
    }
    @Override
    public void onAnimationCancel(Animator animation) {
    }
    @Override
    public void onAnimationRepeat(Animator animation) {
    }
});
valueAnimator.start();

2) 有時候咱們不想實現 Animator.AnimatorListener 接口的所有方法,咱們只想監聽  onAnimationStart,咱們會以下寫:  

ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
valueAnimator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationStart(Animator animation) {
    //xxxx具體實現
    }
});
valueAnimator.start();

應用實例:
3) AnimatorListenerAdapter 類,就是一個接口適配器,代碼如右圖:它空實現了
Animator.AnimatorListener類(src)的全部方法.
4) AnimatorListener 是一個接口.

public abstract class AnimatorListenerAdapter implements 
Animator.AnimatorListener{
    @Override //默認實現
    public void onAnimationCancel(Animator animation) {
    }
    @Override
    public void onAnimationEnd(Animator animation) {
    }
    @Override
    public void onAnimationRepeat(Animator animation) {
    }
    @Override
    public void onAnimationStart(Animator animation) {
    }
    @Override
    public void onAnimationPause(Animator animation) {
    }
    @Override
    public void onAnimationResume(Animator animation) {
    }
}
public static interface AnimatorListener {
    void onAnimationStart(Animator animation);
    void onAnimationEnd(Animator animation);
    void onAnimationCancel(Animator animation);
    void onAnimationRepeat(Animator animation);
}

5) 程序裏的匿名內部類就是Listener 具體實現類

  

 案例說明:

 

  

public interface Interface4 {
	public void m1();
	public void m2();
	public void m3();
	public void m4();
}
//在AbsAdapter 咱們將 Interface4 的方法進行默認實現
public abstract class AbsAdapter implements Interface4 {
	//默認實現
	public void m1() {}
	public void m2() {}
	public void m3() {}
	public void m4() {}
}

public class Client {
	public static void main(String[] args) {
		AbsAdapter absAdapter = new AbsAdapter() {
			//只須要去覆蓋咱們 須要使用 接口方法
			@Override
			public void m1() {
				System.out.println("使用了m1的方法");
			}
		};
		absAdapter.m1();
	}
}

適配器模式在SpringMVC框架應用的源碼分析
1) SpringMvc 中的 HandlerAdapter , 就使用了適配器模式
2) SpringMVC 處理請求的流程回顧:(https://www.cnblogs.com/sanjun/p/9966666.html)(參考使用,侵刪)

  

3) 使用 HandlerAdapter 的緣由分析:
能夠看處處理器的類型不一樣,有多重實現方式,那麼調用方式就不是肯定的,若是須要直接調用
Controller方法,須要調用的時候就得不斷是使用if else來進行判斷是哪種子類而後執行。那麼若是後面要擴展Controller,就得修改原來的代碼,這樣違背了OCP原則。
4) 代碼分析+Debug源碼

5) 動手寫 SpringMVC 經過 適配器設計模式 獲取到對應的 Controller 的源碼
說明:
• Spring 定義了一個適配接口,使得每一種 Controller 有一種對應的適配器實現類
• 適配器代替controller執行相應的方法
• 擴展 Controller 時,只須要增長一個適配器類就完成了SpringMVC的擴展了,
• 這就是設計模式的力量

適配器模式的注意事項和細節
1) 三種命名方式,是根據 src是以怎樣的形式給到Adapter(在Adapter裏的形式)來命名的。
2) 類適配器:以類給到,在Adapter裏,就是將src當作類,繼承;

   對象適配器:以對象給到,在Adapter裏,將src做爲一個對象,持有 

   接口適配器:以接口給到,在Adapter裏,將src做爲一個接口,實現3) Adapter模式最大的做用仍是將本來不兼容的接口融合在一塊兒工做。4) 實際開發中,實現起來不拘泥於咱們講解的三種經典形式

相關文章
相關標籤/搜索