【設計模式】Java設計模式 - 介面卡模式
【設計模式】Java設計模式 - 介面卡模式
:smile: 不斷學習才是王道
:fire: 繼續踏上學習之路,學之分享筆記
:facepunch: 總有一天我也能像各位大佬一樣
:trophy:原創作品,更多關注我CSDN: 一個有夢有戲的人
:facepunch:準備將部落格園、CSDN一起記錄分享自己的學習心得!!!
:full_moon_with_face:分享學習心得,歡迎指正,大家一起學習成長!
今天的內容有點多,也要努力學完!
目錄
- 【設計模式】Java設計模式 - 介面卡模式
簡介
介面卡模式(Adapter Pattern)是作為兩個不相容的介面之間的橋樑。這種型別的設計模式屬於結構型模式,它結合了兩個獨立介面的功能。就像電腦/投影儀那種,電腦要通過接線的方式投影,但是在以前的介面都是VGA介面,然而我們的電腦卻大多都是HDMI型別的,這就需要轉接頭來轉換介面,於是,這個轉接頭就充當著介面卡的身份。
介面卡模式分為:類介面卡模式、物件介面卡模式、介面介面卡模式
1、類介面卡模式
本次實驗使用手機充電的電壓轉換為例,其實就是這樣的,通過介面卡去繼承被適配者,並且實現目標介面。
整體如下:
①、被適配者
手機不能直接使用工作電壓充電,因此需要把工作電壓降壓到能提供手機充電的電壓,這裡先準備好一個工作電壓類,輸出220V標準工作電壓。
package com.lyd.demo.classadapter; /** * @Author: lyd * @Description: 類介面卡 - 工作電壓:220V * @Date: 2022-08-27 */ public class WorkingVoltage { public int outputWorkingPower() { int otp = 220; // 工作電壓輸出220V System.out.println("工作電壓輸出[" + otp + "]V"); return otp; } }
②、充電電壓介面
提供一個獲取充電電壓的介面,提供給介面卡實現。
package com.lyd.demo.classadapter; /** * @Author: lyd * @Description: 類介面卡 - 充電器的電壓 * @Date: 2022-08-27 */ public interface IChargingVoltage { public int outputChangingPower(); }
③、介面卡
在實現充電電壓類的方法中進行電壓轉換。
package com.lyd.demo.classadapter.adapter; import com.lyd.demo.classadapter.IChargingVoltage; import com.lyd.demo.classadapter.WorkingVoltage; /** * @Author: lyd * @Description: 充電介面卡 * @Date: 2022-08-27 */ public class ChargingAdapter extends WorkingVoltage implements IChargingVoltage { public int outputChangingPower() { int workPower = outputWorkingPower(); // 獲得工作電壓 int changingPower = workPower / 44; // 充電電壓 System.out.println("經過介面卡降壓到[" + changingPower + "]V"); return changingPower; } }
④、例項
通過介面卡實現的介面方法去獲得到修改的資料,原理很簡單,就是可以理解為繼承第一個類獲取其屬性資料,在通過實現介面方法去修改。在類介面卡,能達到期望結果,java是單繼承,就是他需要去繼承類,這是他的缺點。
測試類
package com.lyd.demo.classadapter.test; import com.lyd.demo.classadapter.IChargingVoltage; import com.lyd.demo.classadapter.adapter.ChargingAdapter; /** * @Author: lyd * @Description: 測試類介面卡 * @Date: 2022-08-27 */ public class ClassAdapterTest { public static void main(String[] args) {IChargingVoltage chargingVoltage = new ChargingAdapter(); System.out.println("轉換後的電壓:" + chargingVoltage.outputChangingPower()); } }
執行結果
2、物件介面卡模式
由於類介面卡需要繼承,並不是很好,因此,可以使用不繼承的方式,就是需要在介面卡中獲取被適配者的物件。根據合成複用原則,使用組合代替繼承。
①、介面卡類
其他類無需改動,只要將介面卡類的繼承方式改成不繼承的方式。
採用構造器初始化物件來獲得物件。
package com.lyd.demo.objectadapter.adapter; import com.lyd.demo.classadapter.IChargingVoltage; import com.lyd.demo.classadapter.WorkingVoltage; /** * @Author: lyd * @Description: 充電介面卡 * @Date: 2022-08-27 */ public class ChargingAdapter implements IChargingVoltage { private WorkingVoltage workingVoltage; public ChargingAdapter(WorkingVoltage workingVoltage) { this.workingVoltage = workingVoltage; } public int outputChangingPower() { if (workingVoltage != null) { int workPower = workingVoltage.outputWorkingPower(); // 獲得工作電壓 int changingPower = workPower / 44; // 充電電壓 System.out.println("經過介面卡降壓到[" + changingPower + "]V"); return changingPower; } return 0; } }
②、例項
測試的時候只需要將new例項化物件帶進去即可
public static void main(String[] args) { ChargingAdapter chargingAdapter = new ChargingAdapter(new WorkingVoltage()); System.out.println("轉換後的電壓:" + chargingAdapter.outputChangingPower()); }
執行結果
物件適配模式與類適配模式基本上是一樣的,就只是將類適配模式的繼承方式改編成通過構造方法去獲取物件,使得以更加靈活。
3、介面介面卡
不需要實現所有方法,只想實現其中某個方法,可以設計一個抽象介面,並且讓他實現所有介面的空方法,即不需要寫方法體。
①、例1
例如:
定義一個接口裡麵包含幾個未實現的方法
package com.lyd.demo.interfaceadapter; /** * @Author: lyd * @Description: 介面 * @Date: 2022-08-27 */ public interface Interfaces { public void show1(); public void show2(); public void show3(); public void show4(); }
定義抽象介面,並且實現空方法
package com.lyd.demo.interfaceadapter; /** * @Author: lyd * @Description: 介面卡,預設實現空方法,這樣呼叫介面卡的時候就可以根據自己想要的方法去重寫了 * @Date: 2022-08-27 */ public abstract class InterfacesAdapter implements Interfaces { public void show1() { System.out.println("abs show 1"); } public void show2() { System.out.println("abs show 2"); } public void show3() { System.out.println("abs show 3"); } public void show4() { System.out.println("abs show 4"); } }
使用的時候根據自己需要去實現
通過例項化介面卡,在其中去重寫方法,呼叫的時候會使用重寫的方法,如果沒有重寫就是呼叫父類的方法。
package com.lyd.demo.interfaceadapter; /** * @Author: lyd * @Description: 介面介面卡測試 * @Date: 2022-08-27 */ public class Main { public static void main(String[] args) { InterfacesAdapter adapter = new InterfacesAdapter() { @Override public void show1() { // 只重寫一個方法 System.out.println("adapter show 1"); } }; adapter.show1(); adapter.show3(); // 呼叫的時候就是抽象類的空方法 } }
執行結果
②、例2
本例詳情可以看菜鳥教程 http://www.runoob.com/design-pattern/adapter-pattern.html 我用了和他不同的例子,但是結構都是一樣的。
再來一個例子,加入說我需要處理圖片,但是圖片的格式不同,針對不同格式需要不同的方法來處理。
定義介面和特殊格式處理介面
package com.lyd.demo.runoob; /** * @Author: lyd * @Description: <p>http://www.runoob.com/design-pattern/adapter-pattern.html</p> * @Date: 2022-08-27 */ public interface PictureOperate { public void operate(String pictureType, String fileName); }
package com.lyd.demo.runoob; /** * @Author: lyd * @Description: 高階圖片處理 * @Date: 2022-08-27 */ public interface AdvancedPictureOperate { public void operateAi(String fileName); public void operateSvg(String fileName); }
定義處理特殊圖片的類,分別實現各自需要的方法,不需要的放為空方法
package com.lyd.demo.runoob; /** * @Author: lyd * @Description: .Ai圖片的操作 * @Date: 2022-08-27 */ public class AiOperate implements AdvancedPictureOperate{ @Override public void operateAi(String fileName) { System.out.println("操作 " + fileName + " 的ai圖片"); } @Override public void operateSvg(String fileName) { // todo } }
package com.lyd.demo.runoob; /** * @Author: lyd * @Description: .svg圖片的操作 * @Date: 2022-08-27 */ public class SvgOperate implements AdvancedPictureOperate { @Override public void operateAi(String fileName) { // todo } @Override public void operateSvg(String fileName) { System.out.println("操作 " + fileName + " 的svg圖片"); } }
圖片介面卡
根據不同的型別來宣告不同類以及使用對應方法
package com.lyd.demo.runoob; /** * @Author: lyd * @Description: 介面卡 * @Date: 2022-08-27 */ public class PictureAdapter implements PictureOperate{ AdvancedPictureOperate advancedPictureOperate; public PictureAdapter(String pictureType) { if (pictureType.equalsIgnoreCase("ai")) { advancedPictureOperate = new AiOperate(); } else if (pictureType.equalsIgnoreCase("svg")) { advancedPictureOperate = new SvgOperate(); } } @Override public void operate(String pictureType, String fileName) { if (pictureType.equalsIgnoreCase("ai")) { advancedPictureOperate.operateAi(fileName); } else if (pictureType.equalsIgnoreCase("svg")) { advancedPictureOperate.operateSvg(fileName); } } }
操作類
package com.lyd.demo.runoob; /** * @Author: lyd * @Description: * @Date: 2022-08-27 */ public class PhotoOperate implements PictureOperate{ PictureAdapter pictureAdapter; @Override public void operate(String pictureType, String fileName) { if (pictureType.equalsIgnoreCase("ai") || pictureType.equalsIgnoreCase("svg")) { pictureAdapter = new PictureAdapter(pictureType); pictureAdapter.operate(pictureType, fileName); } else if (pictureType.equalsIgnoreCase("jpg")) { // 非特殊格式 System.out.println("不用特殊方法處理:" + fileName); } else { System.out.println("格式錯誤"); } } }
測試
package com.lyd.demo.runoob; /** * @Author: lyd * @Description: * @Date: 2022-08-27 */ public class test { public static void main(String[] args) { PhotoOperate photoOperate = new PhotoOperate(); photoOperate.operate("jpg", "a.jpg"); photoOperate.operate("svg", "b.svg"); photoOperate.operate("ai", "c.ai"); photoOperate.operate("vip", "d.vip"); } }
執行結果
:+1:創作不易,如有錯誤請指正,感謝觀看!記得一鍵三連哦!:+1:
:heartbeat:德德小建議:
理解設計模式不是一件簡單的事情,需要不斷的學習和動手去練習,才能理解。只有掌握好設計模式,才能夠真正的理解SpringAOP和Mybatis的底層原理。各位讀者可以和我一樣,動手敲一敲程式碼,甚至用不同的例子來做,通過debug一步一步除錯,還有就是多看看別人的例子。能夠有助於理解!謝謝各位觀看指點!:heart: :heart: :heart:
- 記一次批量更新整型型別的列 → 探究 UPDATE 的使用細節
- 編碼中的Adapter,不僅是一種設計模式,更是一種架構理念與解決方案
- 執行緒池底層原理詳解與原始碼分析
- 30分鐘掌握 Webpack
- 線性迴歸大結局(嶺(Ridge)、 Lasso迴歸原理、公式推導),你想要的這裡都有
- Django 之路由層
- 【前端必會】webpack loader 到底是什麼
- day42-反射01
- 中心化決議管理——雲端分析
- HashMap底層原理及jdk1.8原始碼解讀
- 詳解JS中 call 方法的實現
- 列印 Logger 日誌時,需不需要再封裝一下工具類?
- 初識設計模式 - 代理模式
- 設計模式---享元模式
- 密碼學奇妙之旅、01 CFB密文反饋模式、AES標準、Golang程式碼
- [ML從入門到入門] 支援向量機:從SVM的推導過程到SMO的收斂性討論
- 從應用訪問Pod元資料-DownwardApi的應用
- Springboot之 Mybatis 多資料來源實現
- Java 泛型程式設計
- CAS核心思想、底層實現