這個總結的挺好的,為了加深印象,我自己再嘗試總結一下
1.定義:
適配器模式把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。
(太官方了,不太好理解,
其實就是要用到兩個不相關的類/接口,但是又沒有源代碼,或者不想修改源代碼,而增加一個類來完成合並使用的目的)
2.實現這個目的有兩個方法,繼承或者組合
2.1.使用繼承(就是所謂的類適配器模式)
2.2.使用組合(所謂的對象適配器模式)
案例: 公司招員工,要求會講中、英、法、日四國語言,同時還很會編程的員工。
招聘要求類 JobNeedSkill 接口:
1 package design.pattern.adapter2; 2 3 public interface JobNeedSkill { 4 void speakChinese(); 5 void speakEnglish(); 6 void speakJapanese(); 7 void speakFrench(); 8 void goodCoding(); 9 }
而這里有個工人,技術超一流,可惜只會說中文。
Worker類:
1 package design.pattern.adapter2; 2 3 public class Worker { 4 public void goodCoding(){ 5 System.out.println("我編程也挺牛的哦"); 6 } 7 8 public void speakChinese(){ 9 System.out.println("我只會說中文呢,能不能請我啊"); 10 } 11 }
招聘測試類 Test:
1 package design.pattern.adapter2; 2 3 public class Test { 4 //招聘員工 5 public static void hireWorker(JobNeedSkill worker){ 6 System.out .println("恭喜你,你被錄用了,展示一下你的技能吧"); 7 8 System.out .println("==============================="); 9 worker.speakChinese(); 10 worker.speakEnglish(); 11 worker.speakFrench(); 12 worker.speakJapanese(); 13 worker.goodCoding(); 14 } 15 16 public static void main(String[] args){ 17 //我是個只會說中文的工人 ,但我編程好 18 Worker me = new Worker(); 19 20 //我們需要一個會說四國語言的員工 21 // hireWorker(me);//直接招聘是不行了,再給他配個步步高點讀機吧 22 23 /* 24 * 以上代碼為初始狀態,后面的代碼是后面根據需求增加的 25 * */ 26 27 //有步步高點讀機,這是使用了繼承的方式,類的適配模式 28 TheManHasBuBuGao bbg = new TheManHasBuBuGao(); 29 hireWorker(bbg); 30 31 System.out.println("*****************\r\n"); 32 //這個自帶助理的,是使用了組合的方式,是對象的適配模式 33 WorkerHasAssistant gfs = new WorkerHasAssistant(me); 34 hireWorker(gfs); 35 } 36 37 }
很明顯,一開始的時候發現,盡管這個人技術很牛,但是只會說中文這一點,實在讓人覺得可惜,
別說我們公司不能招聘了,就連eclipse都提示錯誤了:

不過他的技術的確非常符合我們公司的需要,怎么辦呢,咋取舍呢······
如果,如果他有一台 “步步高點讀機呢”
TheManHasBuBuGao類:
1 package design.pattern.adapter2; 2 //這里使用了繼承的方式 3 public class TheManHasBuBuGao extends Worker implements JobNeedSkill{ 4 5 @Override 6 public void speakJapanese() { 7 System.out.println("媽媽再也不用擔心我的日語了"); 8 } 9 10 @Override 11 public void speakFrench() { 12 System.out.println("哪里不會就點哪里,這樣法語也隨便搞定了"); 13 } 14 15 @Override 16 public void speakEnglish() { 17 System.out.println("So Easy."); 18 } 19 20 }
這樣問題就解決了,步步高點讀機就是好!
不過他說他沒有步步高點讀機,但是他有一個貼身翻譯助理
WorkerHasAssistant類:
1 package design.pattern.adapter2; 2 3 public class WorkerHasAssistant implements JobNeedSkill{ 4 //這個人有自己的助理翻譯,這里是使用了組合的方式 5 private Worker worker; 6 7 //在構造方法中傳進來 8 public WorkerHasAssistant(Worker worker){ 9 this.worker = worker; 10 } 11 12 @Override 13 public void goodCoding() { 14 worker.goodCoding(); 15 } 16 @Override 17 public void speakChinese() { 18 //worker會說,直接用worker 19 worker.speakChinese(); 20 } 21 22 @Override 23 public void speakEnglish() { 24 //英語他不會說,這就要助手出馬翻譯了 25 System.out.println("我是他的翻譯,他說 Hello World."); 26 } 27 28 @Override 29 public void speakJapanese() { 30 //日語他也不會說,這還是要助手出馬翻譯了 31 System.out.println("八嘎"); 32 } 33 34 @Override 35 public void speakFrench() { 36 //每錯,他英語也不行 37 System.out.println("He can say English too."); 38 } 39 40 41 }
最后運行的效果是:

把文章看完是個好習慣,
在最后還要特別說明一下,適配器模式還有一種默認缺省的用法,這個目的跟上面的略微不同,但做法是一致的,
都是增加了一個適配類,哈哈(別跟別的設計模式搞混了哦,同時這種用法在Swing開發里經常用到)
Skill 接口:
1 package design.pattern.adapter2; 2 3 public interface Skill { 4 void sing(); 5 void dance(); 6 void fly(); 7 void cry(); 8 //.......一大堆方法 9 }
如果 Person類直接實現 Skill接口,就會變成這樣:
1 package design.pattern.adapter2; 2 3 public class Person implements Skill{ 4 5 @Override 6 public void sing() { 7 // TODO Auto-generated method stub 8 9 } 10 11 @Override 12 public void dance() { 13 // TODO Auto-generated method stub 14 15 } 16 17 @Override 18 public void fly() { 19 // TODO Auto-generated method stub 20 21 } 22 23 @Override 24 public void cry() { 25 // TODO Auto-generated method stub 26 27 } 28 29 }
必須同時實現Skill接口中的所有方法,但其實我們關注的只是其中某一個方法而已,
所以,這時候就可以增加一個中間類SkillAdapter,這個類也實現了Skill接口,並實現了所有方法,不過是空實現:
1 package design.pattern.adapter2; 2 3 public class SkillAdapter implements Skill{ 4 5 @Override 6 public void sing() { 7 // TODO Auto-generated method stub 8 9 } 10 11 @Override 12 public void dance() { 13 // TODO Auto-generated method stub 14 15 } 16 17 @Override 18 public void fly() { 19 // TODO Auto-generated method stub 20 21 } 22 23 @Override 24 public void cry() { 25 // TODO Auto-generated method stub 26 27 } 28 29 }
而我們在繼承這個中間類(Adapter),再重寫我們所關注的方法就可以了,而無需做過多無謂的操作:
1 package design.pattern.adapter2; 2 3 public class NewPerson extends SkillAdapter{ 4 public void sing(){ 5 System.out.println("我只會唱歌,別的我都不會了"); 6 } 7 }
最后再總結一下:
因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構(也就是去改代碼),
除了這種默認缺省的適配器外,前面的例子都是在沒辦法情況下的辦法而已。
