如何优雅实现支持TCP/串口连接的CommsClass类(规避Object类型)
优雅处理TCP/串口通信类的统一管理方案
这确实是个很典型的抽象与复用问题,你遇到的痛点我太懂了——用Object丢智能提示,拆子类又增加列表维护成本。这里有个完美兼顾的方案:基于抽象接口+适配器模式,既保留Visual Studio的智能提示,又能轻松维护统一的对象列表,还能应对未来的扩展需求。
核心思路
- 提取TCP和串口通信的共通行为定义成接口,让所有通信实现都遵循这个规范
- 针对第三方提供的
SpecificTCPClassFromElsewhere和SpecficSerialClassFromElsewhere,如果它们没有实现统一接口,就用适配器类包装一下,让它们符合我们定义的接口规范 - 在你的
CommsClass中,把master属性定义为这个接口类型,而不是Object或具体类 - 最后通过
CommsClass的不同构造方法,创建对应的适配器实例赋值给master
具体实现代码
第一步:定义统一通信接口
先把TCP和串口共有的操作(比如Read、Write)抽象成接口,这样后续所有通信实现都要遵循这个约定:
Public Interface ICommunications Sub Read() Sub Write() ' 可以根据需求添加其他共通方法,比如Open、Close等 End Interface
第二步:实现适配器类(适配第三方通信类)
因为你提到的TCP和串口类是外部提供的,大概率没有实现我们的接口,所以用适配器模式把它们包装起来:
TCP适配器
Public Class TCPCommAdapter Implements ICommunications ' 持有第三方TCP类的实例 Private ReadOnly _tcpClient As SpecificTCPClassFromElsewhere Public Sub New(host As String, port As String) _tcpClient = New SpecificTCPClassFromElsewhere(host, port) End Sub ' 实现接口的Read方法,内部调用第三方类的Read Public Sub Read() Implements ICommunications.Read _tcpClient.Read() End Sub ' 实现接口的Write方法,内部调用第三方类的Write Public Sub Write() Implements ICommunications.Write _tcpClient.Write() End Sub End Class
串口适配器
Public Class SerialCommAdapter Implements ICommunications ' 持有第三方串口类的实例 Private ReadOnly _serialPort As SpecficSerialClassFromElsewhere Public Sub New(comPort As String) _serialPort = New SpecficSerialClassFromElsewhere(comPort) End Sub Public Sub Read() Implements ICommunications.Read _serialPort.Read() End Sub Public Sub Write() Implements ICommunications.Write _serialPort.Write() End Sub End Class
第三步:改造你的CommsClass
现在把master属性改成我们定义的ICommunications接口类型,这样Visual Studio就能提供完整的智能提示了:
Public Class CommsClass ' 现在是接口类型,智能提示拉满! Public Property Master As ICommunications ' TCP构造方法:创建TCP适配器实例 Public Sub New(host As String, port As String) Master = New TCPCommAdapter(host, port) End Sub ' 串口构造方法:创建串口适配器实例 Public Sub New(comPort As String) Master = New SerialCommAdapter(comPort) End Sub ' 保留你原来的所有辅助方法,比如: Public Sub SendHeartbeat() ' 这里调用Master.Write会有智能提示,不用猜方法名 Master.Write() End Sub ' 其他辅助方法... End Class
第四步:统一维护对象列表
现在维护列表就和你原来的需求完全一致,所有实例都是CommsClass类型,不用区分TCP还是串口:
Public Sub Main() Dim masters As List(Of CommsClass) = New List(Of CommsClass)() ' 添加TCP通信实例 masters.Add(New CommsClass("127.0.0.1", "8080")) ' 添加串口通信实例 masters.Add(New CommsClass("COM3")) ' 遍历列表统一操作,不用判断类型 For Each comm In masters comm.Master.Read() comm.SendHeartbeat() ' 调用辅助方法 Next End Sub
方案优势
- 保留智能提示:
Master是接口类型,Visual Studio会自动提示Read、Write等方法,再也不用靠记忆或者查文档 - 列表维护简单:所有通信实例都统一在
List(Of CommsClass)中,不用处理子类的差异,遍历、增删都很方便 - 扩展性极强:以后如果要加UDP、蓝牙等其他通信方式,只需要新增一个适配器类实现
ICommunications,再给CommsClass加个对应的构造方法就行,完全不用修改现有代码 - 解耦设计:
CommsClass不再依赖具体的TCP/串口实现,而是依赖抽象接口,符合面向对象的依赖倒置原则,代码更健壮
内容的提问来源于stack exchange,提问作者Gavin Hill
相关产品推荐
相关产品推荐

