Android | java安卓上位機開發 策略模式實現多連接方式的擴展
在進行安卓上位機項目開發時,最初的通訊方式只有一種——低功耗藍牙,后續由于項目需求,新增了wifi通訊模式,在新增通訊模式后,需要對原有代碼進行重構,以實現新增功能,并且需要考慮到增加其他通訊方式的擴展性,于是嘗試了兩種方式:
兩種方案均通過工廠模式創建對象,核心差異在于 “通訊邏輯與設備屬性的綁定方式”:
- 多態(繼承抽象類):將設備屬性(名稱、地址等)和通訊方法(連接、發送等)封裝在抽象類中,具體通訊方式(藍牙、TCP)通過繼承抽象類實現。
例:AbstractDevice定義設備通用屬性和抽象通訊方法,BleDevice、TcpDevice分別實現藍牙和 TCP 的具體邏輯。 - 策略模式:將通訊邏輯抽離為獨立策略接口,設備屬性與通訊策略通過 “組合” 關聯。
例:ConnectionStrategy接口定義通訊標準,BleStrategy、TcpStrategy實現具體通訊邏輯;Device類持有設備屬性,并通過注入不同策略實現通訊方式切換。
方法一——多態:
第一種,也就是最先采用并實現的一種方法,構造一個抽象父類,聲明必要的方法,不同連接方式通過繼承抽象對象,進行獨立的實現,來實現各自的連接方法。
例:
package StrategyPattern.poly;
/**
* 頂層抽象類
*/
public abstract class AbstractDevice {
private String deviceName;
private String address;
private String deviceType;
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
/**
* 設備連接方法
* @return
*/
public abstract boolean connect();
/**
* 設備斷開方法
* @return
*/
public abstract boolean disconnect();
/**
* 發送數據
* @param data 數據
* @return
*/
public abstract boolean write(byte[] data);
/**
* 接收數據(在具體的子類中實現,在具體實現中,將接收到的數據進行轉發或其他操作)
* @param data 接收到的數據
* @return
*/
public abstract boolean recv(byte[] data);
}
package StrategyPattern.poly;
public class BleDevice extends AbstractDevice{
@Override
public boolean connect() {
return false;
}
@Override
public boolean disconnect() {
return false;
}
@Override
public boolean write(byte[] data) {
return false;
}
@Override
public boolean recv(byte[] data) {
return false;
}
}
package StrategyPattern.poly;
public class TcpDevice extends AbstractDevice{
@Override
public boolean connect() {
return false;
}
@Override
public boolean disconnect() {
return false;
}
@Override
public boolean write(byte[] data) {
return false;
}
@Override
public boolean recv(byte[] data) {
return false;
}
}
方法二——策略模式:
策略模式則是將連接方式抽離為單獨的策略接口,使用接口來進行操作。在構造對象時,通過不同的接口實現,來進行不同方式的設備連接。
package StrategyPattern.strategy;
public interface ConnectionStrategy {
public interface ConnectionCallback{
void onConnected();
void onError(Exception e);
void onDisconnected();
void onDataReceived(byte[] data);
}
/**
* 建立連接
* @param callback 連接回調
* @return 連接是否成功啟動
*/
boolean connect(ConnectionCallback callback);
/**
* 斷開連接
* @return 斷開是否成功
*/
boolean disconnect();
/**
* 發送數據
* @param data 要發送的數據
* @return 發送是否成功
*/
boolean writeData(byte[] data);
/**
* 獲取連接狀態
* @return 是否已連接
*/
boolean isConnected();
/**
* 釋放資源
*/
void release();
}
package StrategyPattern.strategy;
public class BleStrategy implements ConnectionStrategy{
private ConnectionCallback callback;
@Override
public boolean connect(ConnectionCallback callback) {
return false;
}
@Override
public boolean disconnect() {
return false;
}
@Override
public boolean writeData(byte[] data) {
return false;
}
@Override
public boolean isConnected() {
return false;
}
@Override
public void release() {
}
}
package StrategyPattern.strategy;
public class TcpStrategy implements ConnectionStrategy{
private ConnectionCallback callback;
@Override
public boolean connect(ConnectionCallback callback) {
return false;
}
@Override
public boolean disconnect() {
return false;
}
@Override
public boolean writeData(byte[] data) {
return false;
}
@Override
public boolean isConnected() {
return false;
}
@Override
public void release() {
}
}
package StrategyPattern.strategy;
public class Device {
private String deviceName;
private String address;
private String deviceType;
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
private ConnectionStrategy strategy;
public Device(ConnectionStrategy strategy){
this.strategy = strategy;
}
public boolean connect(){
return this.strategy.connect(new ConnectionStrategy.ConnectionCallback() {
@Override
public void onConnected() {
// 連接成功回調
}
@Override
public void onError(Exception e) {
// 錯誤提示
}
@Override
public void onDisconnected() {
// 連接斷開回調
}
@Override
public void onDataReceived(byte[] data) {
// 接受到數據
}
});
}
public boolean disconnect(){
// 具體實現
return true;
}
public boolean isConnected(){
// 具體實現
return true;
}
}
總結(讓ai總結的)
多態方法(繼承抽象類)的優缺點
優點
- 實現簡單直接
通過繼承抽象類,每個具體設備(如 BleDevice、TcpDevice)直接實現所需方法,符合面向對象的基本設計原則。 - 代碼結構清晰
功能和狀態集中在一個類中,便于理解和維護。例如,設備的連接狀態、生命周期管理都封裝在子類中。 - 強類型關聯
設備類型與通信方式緊密綁定,適用于設備與通信方式一一對應的場景。例如,BleDevice 只能通過藍牙通信。
缺點
- 擴展性受限
新增通信方式需要創建新的子類,導致子類數量膨脹。例如,若后續增加 USB、NFC 等通信方式,類的數量會急劇增加。 - 代碼復用困難
若不同通信方式有共同邏輯(如數據解析、錯誤處理),難以在子類間復用,可能導致代碼冗余。 - 依賴關系復雜
高層模塊直接依賴具體子類,違反依賴倒置原則。例如,若需要切換通信方式,可能需要修改多處代碼。 - 回調邏輯處理不便
若通信過程需要異步回調(如連接狀態通知),需要在抽象類中預先定義接口或方法,增加設計復雜度。
策略模式的優缺點
優點
- 高擴展性
新增通信方式只需實現ConnectionStrategy接口,無需修改現有代碼,符合開閉原則。例如,增加 WiFi 通信只需創建WiFiStrategy類。 - 代碼復用性好
可在策略類間共享通用邏輯(如數據緩存、異常處理),通過組合而非繼承實現功能復用。 - 松耦合設計
Device類與具體通信實現解耦,便于切換和擴展通信方式。例如,同一設備可在運行時動態切換藍牙、TCP 等通信策略。 - 便于單元測試
策略類可獨立測試,無需依賴具體設備實現,提高測試覆蓋率。
缺點
- 類數量增加
每個通信方式需要獨立的策略類,可能導致類數量增多,但結構更清晰。 - 狀態管理復雜
若通信狀態需要在多個策略間共享,需額外設計狀態管理機制,增加復雜度。 - 初始設計復雜度高
需要設計抽象策略接口、回調機制等,初期投入成本較高。
浙公網安備 33010602011771號