您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么使用Adapter Pattern”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么使用Adapter Pattern”吧!
適配器模式(Adapter Pattern)- 將一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作
使用適配器模式其實就是把一個接口或者類轉換成其他的接口和類,使其可以和其他模塊一起工作,也可以被稱為包裝模式(Wrapper),同樣有包裝的功能還有裝飾模式。適配器模式主要應用于想要復用現有的類,但是接口又與復用環境不一致的情況下
經常換手機的人可能會知道,手機的充電接口有幾種,安卓的接口現在大多是Type-C
了,一些低端機可能還在用Micro USB
接口,而蘋果則是用Lightining
接口,假如我現在買了個新手機是Type-C
接口,那我以前的那個Micro USB
數據線還能不能繼續用呢,是可以用的,只不過需要加上一個轉接頭,這個轉接頭便是一個適配器
適配器模式角色
目標類(Target):定義客戶所需接口,可以是一個抽象類或接口,也可以是具體類
適配者(Adaptee):需要被適配的角色,它是已經存在的類或對象,適配者類一般是一個具體類,包含了客戶希望使用的業務方法,在某些情況下可能沒有適配者類的源代碼
適配器(Adapter):它的職責就是要把適配者轉換成目標角色,對Adaptee和Target進行適配,在對象適配器中,它通過繼承Target并關聯一個Adaptee對象使二者產生聯系
適配器有兩種分類:對象適配器、類(或接口)適配器。在對象適配器模式中,適配器與適配者之間是關聯關系;在類適配器模式中,適配器與適配者之間是繼承(或實現)關系
對象適配器
類適配器
優點
可以讓兩個沒有關系的類在一起運行,引入一個適配器,可以不用修改原有代碼
增加類的透明度,客戶端只調用Target,不關心具體實現
提高類的復用度,原適配者類的功能還可以正常使用
靈活性和擴展性非常好,符合“開閉原則”
使用場景
系統需要使用一些現有的類,而這些類的接口(如方法名)不符合系統的需要,甚至沒有這些類的源代碼
修改已投產的接口,可以考慮適配器模式
注意,適配器模式通常是用來解決系統擴展的問題,在系統開發過程中或已經項目維護中,當需要引入第三方的功能或要擴展的內容不符合原有設計的時候,才會考慮通過適配器模式來減少代碼修改帶來的風險。另外,項目一定要遵守依賴倒置原則和里氏替換原則,這樣在使用適配器模式時,才不會有太多改動
總的來說,適配器模式屬于補償模式,專門用來在系統后期擴展、修改時使用,但要注意不要過度使用適配器模式
前些天剛入手一臺新手機,滿心歡喜啊,拿到手就忍不住開始“摩擦“,掂量一圈發現現在的手機是越來越好看、越來越薄了呀,一開心就想著拿出我的耳機想要沉浸在音樂的世界里,可下一秒蒙圈了,泥馬沒有耳機孔。原來啊,為了把手機做的更薄、更美,手機廠家犧牲了傳統的3.mm耳機插孔,而使用復用充電接口Type-C,這下難道我又要去再搞一條Type-C接口的耳機嗎?答案是可以不用,可以買一個接口轉換器
Target目標類 - 要求使用Type-C接口
public interface TypeC { void useTypeCPort(); }
Adaptee適配者 - 被適配的對象
public interface Headset { void listen(); } public class CommonHeadset implements Headset { @Override public void listen() { System.out.println("使用3.5mm耳機享受音樂..."); } }
Adapter適配器 - 把適配對象和目標類關聯起來,達到轉換的目的
public class CommonHeadsetAdapter implements TypeC { private CommonHeadset headset; public CommonHeadsetAdapter(CommonHeadset headset){ this.headset = headset; } @Override public void useTypeCPort() { System.out.println("使用Type-C轉接頭"); this.headset.listen(); } }
測試
@Test public void adapterTest(){ CommonHeadset headset = new CommonHeadset(); CommonHeadsetAdapter headsetAdapter = new CommonHeadsetAdapter(headset); headsetAdapter.useTypeCPort(); }
測試結果
使用Type-C轉接頭 使用3.5mm耳機享受音樂...
上面的是對象適配器,下面的是類適配器的做法
public class CommonHeadsetAdapter2 extends CommonHeadset implements TypeC { @Override public void useTypeCPort() { System.out.println("使用Type-C轉接頭"); super.listen(); } }
在我看來適配器模式主要是用在系統的擴展,或接入第三方接口。我們都不想破壞原有的設計和結構,為了適應新的需求,在它們之間增加一個適配層,這個適配器角色為我們轉換數據或做連接。這樣新的接口就能流暢調用舊的接口,達到復用的目的,符合開閉原則
要想理解適配器模式的應用或自己使用適配器,只要理清角色分工就很容易了。需要擴展一個怎樣的新需求 (目標角色),但不改變原有的設計結構 (被適配角色),這個被適配角色可以是現有的接口、對象、類或第三方API,然后使用一個中間角色 (適配器) 做數據轉換或功能調用,使其滿足新需求
JDBC - 驅動程序 - 數據庫引擎API
Java程序是通過JDBC來跟數據庫連接的,JDBC給出了一套抽象的接口,即目標接口。而各種數據庫就是我們要適配的對象的,在JDBC接口和數據庫引擎API之間需要一個適配器,而這個適配器就是驅動程序。(比如MySql的連接程序就是一個適配器,它把數據庫的API操作適配成JDBC的Java操作)
Java I/O 庫使用了適配器模式
如ByteArrayInputStream
是一個適配器類,它繼承了InputStream
的接口(目標接口),并且封裝了一個 byte 數組(被適配者)。它將一個 byte 數組的接口適配成InputStream
流處理器的接口;
FileOutputStream
繼承了 OutputStream
類型,同時持有一個對 FileDiscriptor
對象的引用。這是一個將 FileDiscriptor
接口適配成 OutputStream
接口形式的對象適配器模式;
Reader
類型的原始流處理器都是適配器模式的應用。StringReader
是一個適配器類,StringReader
類繼承了Reader
類型,持有一個對String
對象的引用。它將String
的接口適配成 Reader
類型的接口
Spring AOP中的適配器模式
在Spring的Aop中,使用Advice(通知)來增強被代理類的功能。
Advice的類型有:MethodBeforeAdvice
、AfterReturningAdvice
、ThrowsAdvice
,而每個類型的Advice都有對應的攔截器:MethodBeforeAdviceInterceptor
、AfterReturningAdviceInterceptor
、ThrowsAdviceInterceptor
。Spring需要將每個Advice都封裝成對應的攔截器類型,返回給容器,所以需要使用適配器模式對Advice進行轉換
在這個應用中,Advice增強類其實只是普通的對象(被適配角色),而我們的目標是通過攔截器對切入點增強功能,所以通過適配器將我們的Advice適配成攔截器達到增強切入點的目的
Adaptee適配者類
public interface MethodBeforeAdvice extends BeforeAdvice { void before(Method method, Object[] args, @Nullable Object target) throws Throwable; } public interface AfterReturningAdvice extends AfterAdvice { void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable; } public interface ThrowsAdvice extends AfterAdvice { }
Target目標接口
public interface AdvisorAdapter { // 判斷是否支持該增強,即是否匹配 boolean supportsAdvice(Advice advice); // 獲取對應的攔截器 MethodInterceptor getInterceptor(Advisor advisor); }
Adapter適配器
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof MethodBeforeAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); return new MethodBeforeAdviceInterceptor(advice); } } class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof AfterReturningAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice(); return new AfterReturningAdviceInterceptor(advice); } } class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable { @Override public boolean supportsAdvice(Advice advice) { return (advice instanceof ThrowsAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { return new ThrowsAdviceInterceptor(advisor.getAdvice()); } }
到此,相信大家對“怎么使用Adapter Pattern”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。