【設計模式】Java設計模式 - 配接器模式
?? 不斷學習才是王道
?? 繼續踏上學習之路,學之分享筆記
?? 總有一天我也能像各位大佬一樣
??原創作品,更多關注我CSDN: 一個有夢有戲的人
??準備將博客園、CSDN一起記錄分享自己的學習心得!!!
??分享學習心得,歡迎指正,大家一起學習成長!
今天的內容有點多,也要努力學完!
目錄- 【設計模式】Java設計模式 - 配接器模式
- 簡介
- 1、類配接器模式
- ①、被適配者
- ②、充電電壓介面
- ③、配接器
- ④、實體
- 2、物件配接器模式
- ①、配接器類
- ②、實體
- 3、介面配接器
- ①、例1
- ②、例2

簡介
配接器模式(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
本例詳情可以看菜鳥教程 https://www.runoob.com/design-pattern/adapter-pattern.html 我用了和他不同的例子,但是結構都是一樣的,
再來一個例子,加入說我需要處理圖片,但是圖片的格式不同,針對不同格式需要不同的方法來處理,
定義介面和特殊格式處理介面
package com.lyd.demo.runoob;
/**
* @Author: lyd
* @Description: <p>https://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");
}
}
運行結果

??創作不易,如有錯誤請指正,感謝觀看!記得一鍵三連哦!??
??德德小建議:
理解設計模式不是一件簡單的事情,需要不斷的學習和動手去練習,才能理解,只有掌握好設計模式,才能夠真正的理解SpringAOP和Mybatis的底層原理,各位讀者可以和我一樣,動手敲一敲代碼,甚至用不同的例子來做,通過debug一步一步除錯,還有就是多看看別人的例子,能夠有助于理解!謝謝各位觀看指點!?? ?? ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/505547.html
標籤:其他
上一篇:《游戲設計模式》筆記 01 序章
下一篇:設計模式概述及UML圖決議
