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 等通信策略。 - 便于单元测试
策略类可独立测试,无需依赖具体设备实现,提高测试覆盖率。
缺点
- 类数量增加
每个通信方式需要独立的策略类,可能导致类数量增多,但结构更清晰。 - 状态管理复杂
若通信状态需要在多个策略间共享,需额外设计状态管理机制,增加复杂度。 - 初始设计复杂度高
需要设计抽象策略接口、回调机制等,初期投入成本较高。
Android | java安卓上位机开发 策略模式实现多连接方式的扩展的更多相关文章
- USBCAN的使用和上位机开发(MFC)
USBCAN使用手册 参见:https://blog.51cto.com/12572800/2062839 1. USB CAN软件安装与硬件接线 USB CAN是常用的CAN测试工具.它的软件资料存 ...
- 【专题教程第8期】基于emWin模拟器的USB BULK上位机开发,仅需C即可,简单易实现
说明:1.如果你会emWin话的,就可以轻松制作上位机.做些通信和控制类上位机,比使用C#之类的方便程度一点不差,而且你仅会C语言就可以.2.并且成功将emWin人性化,可以做些Windows系统上的 ...
- Java设计模式(18)策略模式(Strategy模式)
Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线, ...
- C#上位机开发(二)—— Hello,World
上一篇大致了解了一下单片机实际项目开发中上位机开发部分的内容以及VS下载与安装,按照编程惯例,接下来就是“Hello,World!” 1.新建C#项目工程 首先选择新建Windows窗体应用(.NET ...
- Winform 快速开发框架,上位机开发,工控机程序开发,CS程序开发
1.当客户让你做个CS程序时,当你手上一穷二白,所有都要重复造轮,你是不是很烦. 2.但如果有一个通用的,快速开发框架,就可以把你从这些基础的工作解救出来,你专注做业务就好了. 3.本人其中一个项目的 ...
- 上位机开发之三菱Q系列PLC通信实践
经常关注我们公众号或者公开课的学员(如果还没有关注的话,左上角点击一波关注)应该知道,我们会经常使用西门子PLC,其实对于其他品牌的PLC,我们都会讲到,包括三菱.欧姆龙.基恩士.松下及国产台达.信捷 ...
- 上位机开发之三菱FX3U以太网通信实践
上次跟大家介绍了一下上位机与三菱Q系列PLC通信的案例,大家可以通过点击这篇文章:上位机开发之三菱Q系列PLC通信实践(←戳这里) 今天以三菱FX3U PLC为例,跟大家介绍一下,如何实现上位机与其之 ...
- 上位机开发之西门子PLC-S7通信实践
写在前面: 就目前而言,在中国的工控市场上,西门子仍然占了很大的份额,因此对于上位机开发而言,经常会存在需要与西门子PLC进行通信的情况.然后对于西门子PLC来说,通信方式有很多,下面简单列举一下: ...
- C#上位机开发(一)—— 了解上位机
在单片机项目开发中,上位机也是一个很重要的部分,主要用于数据显示(波形.温度等).用户控制(LED,继电器等),下位机(单片机)与 上位机之间要进行数据通信的两种方式都是基于串口的: USB转串口 — ...
- 周立功USBCAN-II 上位机开发(MFC)
使用的USB转CAN的设备是周立功的USBCAN-II,在购买的时候,会有上位机二次开发的库文件.例程和API文档等材料,可以参考. 1.库函数的调用 首先,把库函数文件都放在工作目录下.库函数文件总 ...
随机推荐
- 楚慧杯Misc—复现
gza_CrackerCrack_me 追踪tcp流量 找到字典 保存字典,上流量一把梭 base64解密 特殊流量2 一把梭出个www.zip 打开,是个RSA <?php $cmd = @$ ...
- HanioTower(java)
package javaBasic; import java.util.Scanner; public class HanioTower { public static void main(Strin ...
- echart的使用心得
前言:由于本人在最近的公司中接触了一些与数据可视化有关的项目,所以特意花了一些时间去学习了echarts,以下是我个人在使用与学习echarts的一些心得体会. 1.首先我们需要知道的是什么是Echa ...
- Nohup 启动程序未指定输出日志,导致磁盘空间被占满的解决方案
1. 问题原因 当使用 nohup 启动程序时,默认情况下,标准输出(stdout)和标准错误(stderr)都会被重定向到 nohup.out 文件.例如: nohup python my_scri ...
- Target JRE version (1.8.0_201) does not match project JDK version (java version "1.7"), will use sources from JDK: 1.8
问题描述:IntelliJ IDEA 启动项目时,常常提示Target JRE version (1.8.0_201) does not match project JDK version (java ...
- [译]MIT6.824_1.1分布式系统介绍——驱动力与挑战
这是6.824分布式系统课程,我会开始用简明的介绍我所认为的分布式系统. 分布式系统的核心是通过网络以完成一致任务的一组协作计算机. 因此我们将在本课程中重点介绍各种实例,例如大型网站的存储或MapR ...
- JDBC连接数据库增删改查实例
查询所有 dao层代码: package example; import java.sql.Connection; import java.sql.DriverManager; import java ...
- Golang defer
一.多个延迟执行语句的处理顺序 Go语言中defer语句会将起后面跟随的语句进行延迟处理,在defer归属的函数即将返回时,将延迟处理的语句按照defer的逆序进行执行,也就是说先被defer的语句最 ...
- 爆肝整理!0 基础 AI 编程必拿的 3 大神器:源码一键跑 + 推广秘籍 + 私教答疑
2025年预期的 AI 应用爆发并没有到来,但是编程领域却是个特例.AI 编程工具正在引领大模型落地的浪潮,展现出明显的产品市场契合度(Product Market Fit,PMF). 那么在全面智能 ...
- ChatMoney让你体验古诗词的快乐
本文由 ChatMoney团队出品 介绍说明 在中华传统文化的璀璨星空里,诗词宛如熠熠生辉的明珠,而飞花令则是其中一颗独特而耀眼的星辰.如今,我们自豪地为您推出专为孩子精心打造的飞花令机器人,为孩子们 ...