当前位置: 首页 > news >正文

PLC结构化文本设计模式——适配器模式(Adapter Pattern)

PLC Structured Text Design Patterns

PLC结构化文本设计模式——适配器模式(Adapter Pattern)

介绍

适配器模式(Adapter Pattern)充当两个不兼容接口之间的桥梁,属于结构型设计模式。它通过一个中间件(适配器)将一个类的接口转换成客户期望的另一个接口,使原本不能一起工作的类能够协同工作。适配器模式是一种软件设计模式,旨在解决不同接口之间的兼容性问题。适配器通过继承或依赖现有对象,并实现所需的目标接口。——Java 适配器模式|菜鸟教程

使用场景

  • 需要使用现有类,但其接口不符合系统需求。
  • 希望创建一个可复用的类,与多个不相关的类(包括未来可能引入的类)一起工作,这些类可能没有统一的接口。
  • 通过接口转换,将一个类集成到另一个类系中。

生活中经典的例子,手机适配器或电脑适配器,连接手机或电脑端的接口为USB,连接充电插座端是两孔/三孔,充电就通过中间的适配器。

优缺点

  • 优点

    • 促进了类之间的协同工作,即使它们没有直接的关联。
    • 提高了类的复用性。
    • 增加了类的透明度。
    • 提供了良好的灵活性。
  • 缺点

    • 过度使用适配器可能导致系统结构混乱,难以理解和维护。
    • 由于只能继承一个类,因此只能适配一个类,且目标类必须是抽象的。

    Java 适配器模式|菜鸟教程

伪代码

socket通讯串口通讯为例,设计适配器用以适配客户端接口I_Communication

INTERFACE I_Interface EXTENDS __SYSTEM.IQueryInterface

串口通讯接口,接口的属性成员和方法成员与客户端接口I_Communication不一致,因此需要进行适配。

INTERFACE I_SerialCom EXTENDS I_InterfacePROPERTY BaudRate : INT
Get()
------
PROPERTY DataBits : INT
Get()
------
PROPERTY IsConnected : BOOL
Get()
------
PROPERTY Parity : INT
Get()
------
PROPERTY PortName : STRING
Get()
------
PROPERTY StopBits : INT
Get()
------
METHOD Close : BOOL
VAR_INPUT
END_VAR
------
METHOD Open : BOOL
VAR_INPUT
END_VAR
------
METHOD SendData : STRING
VAR_INPUTdata : STRING;
END_VAR

Socket通讯接口,接口的属性成员和方法成员与客户端接口I_Communication不一致,因此需要进行适配。

INTERFACE I_Socket EXTENDS I_InterfaceMETHOD Connect : BOOL
VAR_INPUT
END_VAR
------
METHOD Disconnect : BOOL
VAR_INPUT
END_VAR
------
METHOD SendMessage : STRING
VAR_INPUTmessage : STRING;
END_VAR
------
PROPERTY IpAddress : STRING
Get()
------
PROPERTY IsConnected : BOOL
Get()
------
PROPERTY Port : INT
Get()

客户端需要系统通用接口,直接工作在业务中。前面的I_SerialComI_Socket接口需要适配I_Communication接口。

INTERFACE I_Communication EXTENDS I_InterfaceMETHOD Connect : BOOL
VAR_INPUT
END_VAR
------
METHOD Disconnect : BOOL
VAR_INPUT
END_VAR
------
METHOD Send : STRING
VAR_INPUTsContent : STRING;
END_VAR
------
PROPERTY IsConnected : BOOL
Get()

FB_SerialCom串口通讯,实现I_SerialCom接口。

FUNCTION_BLOCK FB_SerialCom IMPLEMENTS I_SerialCom
VAR_IsConnected : BOOL := FALSE;_BaudRate 	 : INT;_DataBits	 : INT;_Parity		 : INT;_PortName	 : STRING;_StopBits	 : INT;
END_VAR
------
PROPERTY BaudRate : INT
Get:BaudRate := THIS^._BaudRate;
------
PROPERTY DataBits : INT
Get:DataBits := THIS^._DataBits;
------
PROPERTY IsConnected : BOOL
Get:IsConnected := THIS^._IsConnected;
------
PROPERTY Parity : INT
Get:Parity := THIS^._Parity;
------
PROPERTY PortName : STRING
Get:PortName := THIS^._PortName;
------
PROPERTY StopBits : INT
Get:StopBits := THIS^._StopBits;
------
METHOD FB_init : BOOL
VAR_INPUTbInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)bInCopyCode : BOOL;  // if TRUE, the instance afterwards gets moved into the copy code (online change)portName : STRING; // 端口号baudRate : INT; // 波特率parity   : INT; // 校验位dataBits : INT; // 数据位stopBits : INT; // 停止位
END_VARTHIS^._PortName := portName;
THIS^._BaudRate := baudRate;
THIS^._Parity 	:= parity;
THIS^._DataBits := dataBits;
THIS^._StopBits := stopBits;
------
METHOD Open : BOOL
VAR_INPUT
END_VARADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Serial port com port name:%s', strArg := THIS^._PortName);
ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Serial port com baud rate:%s', strArg := TO_STRING(THIS^._BaudRate));
ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Serial port com parity:%s', strArg := TO_STRING(THIS^._Parity));
ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Serial port com data bits:%s', strArg := TO_STRING(THIS^._DataBits));
ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Serial port com stop bits:%s', strArg := TO_STRING(THIS^._StopBits));// 打开串口逻辑
// ************
// 打开串口逻辑
THIS^._IsConnected := TRUE;ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Serial port com state:%s', strArg := 'Opened');
------
METHOD SendData : STRING
VAR_INPUTdata	: STRING;
END_VAR// 串口发送数据逻辑
// ******************
// 串口发送数据逻辑ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Serial port com send data:%s', strArg := data);
------
METHOD Close : BOOL// 关闭串口逻辑
// ***********
// 关闭串口逻辑
THIS^._IsConnected := FALSE;ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Serial port com state:%s', strArg := 'Closed');

FB_Socket通讯实体类,实现I_Socket接口

FUNCTION_BLOCK FB_Socket IMPLEMENTS I_Socket
VAR_isConnect : BOOL;_ipAddress : STRING;_port	   : INT;
END_VAR
------
PROPERTY IpAddress : STRING
Get:IpAddress := THIS^._ipAddress;
------
PROPERTY Port : INT
Get:Port := THIS^._port;
------
PROPERTY IsConnected : BOOL
Get:IsConnected := THIS^._isConnect;
------
METHOD FB_init : BOOL
VAR_INPUTbInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)bInCopyCode : BOOL;  // if TRUE, the instance afterwards gets moved into the copy code (online change)ipAddress	: STRING; // IP地址port		: INT; // 端口号
END_VARTHIS^._ipAddress := ipAddress;
THIS^._port		 := port;
------
METHOD Connect : BOOL
VAR_INPUT
END_VARADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Socket ip address:%s', strArg := THIS^._ipAddress);ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Socket port:%s', strArg := TO_STRING(THIS^._port));// socket连接逻辑
// **************
// socket连接逻辑THIS^._isConnect := TRUE;ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Socket state:%s', strArg := 'Connected');
------
METHOD SendMessage : STRING
VAR_INPUTmessage	: STRING;
END_VAR// socket发送数据逻辑
// ******************
// socket发送数据逻辑
ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Socket send message:%s', strArg := message);
------
METHOD Disconnect : BOOL// socket断开连接逻辑
// **************
// socket断开连接逻辑
THIS^._isConnect := FALSE;ADSLOGSTR(msgCtrlMask :=ADSLOG_MSGTYPE_LOG, msgFmtStr :='Socket state:%s', strArg := 'DisConnected');
FUNCTION_BLOCK FB_SerialComAdapter IMPLEMENTS I_Communication
VAR_iSerialCom : I_SerialCom;
END_VAR
------
PROPERTY IsConnected : BOOL
Get:IsConnected := THIS^._iSerialCom.IsConnected;
------
METHOD FB_init : BOOL
VAR_INPUTbInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)bInCopyCode : BOOL;  // if TRUE, the instance afterwards gets moved into the copy code (online change)iSerialCom : I_SerialCom; // 串口通讯
END_VARTHIS^._iSerialCom := iSerialCom;
------
METHOD Connect : BOOLTHIS^._iSerialCom.Open();
------
METHOD Send : STRING
VAR_INPUTsContent	: STRING;
END_VARTHIS^._iSerialCom.SendData(sContent);
------
METHOD Disconnect : BOOLTHIS^._iSerialCom.Close();

Socket通讯适配器FB_SocketAdapter,实现I_Communication客户端接口

FUNCTION_BLOCK FB_SocketAdapter IMPLEMENTS I_Communication
VAR_iSocket : I_Socket;
END_VAR
------
PROPERTY IsConnected : BOOL
Get:IsConnected := THIS^._iSocket.IsConnected;
------
METHOD FB_init : BOOL
VAR_INPUTbInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)bInCopyCode : BOOL;  // if TRUE, the instance afterwards gets moved into the copy code (online change)iSocket : I_Socket; // Socket通讯
END_VARTHIS^._iSocket := iSocket;
------
METHOD Connect : BOOLTHIS^._iSocket.Connect();
------
METHOD Send : STRING
VAR_INPUTsContent	: STRING;
END_VARTHIS^._iSocket.SendMessage(sContent);
------
METHOD Disconnect : BOOLTHIS^._iSocket.Disconnect();

客户端主程序MAIN运行测试,声明fbSerialComfbSocket两个与客户端不同的接口通讯实例,并初始化连接参数。实例化FB_SerialComAdapterFB_SocketAdapter初始化分别传入fbSerialComfbSocket实例。客户端根据实际需求使用I_Communication接口接收适配器实例,执行ConnectSendDisconnect方法测试接口。

PROGRAM MAIN
VARfbSerialCom		: FB_SerialCom('COM1',9600,0,8,1);fbSocket		: FB_Socket('192.168.0.1',801);fbSerialComAdapter 	: FB_SerialComAdapter(fbSerialCom);fbSocketAdapter		: FB_SocketAdapter(fbSocket);iCommunication : I_Communication;bTest	 : BOOL;
END_VARIF bTest THENiCommunication := fbSerialComAdapter;iCommunication.Connect();iCommunication.Send('this is serial com data');iCommunication.Disconnect();iCommunication := fbSocketAdapter;iCommunication.Connect();iCommunication.Send('this is socket message');iCommunication.Disconnect();bTest := FALSE;
END_IF

日志输出结果:

MSG | 'PlcTask' (350): Serial port com port name:COM1
MSG | 'PlcTask' (350): Serial port com baud rate:9600
MSG | 'PlcTask' (350): Serial port com parity:0
MSG | 'PlcTask' (350): Serial port com data bits:8
MSG | 'PlcTask' (350): Serial port com stop bits:1
MSG | 'PlcTask' (350): Serial port com send data:this is serial com data
MSG | 'PlcTask' (350): Serial port com state:ClosedMSG | 'PlcTask' (350): Socket ip address:192.168.0.1
MSG | 'PlcTask' (350): Socket port:801
MSG | 'PlcTask' (350): Socket state:Connected
MSG | 'PlcTask' (350): Socket send message:this is socket message
MSG | 'PlcTask' (350): Socket state:DisConnected

日志输出结果显示,客户端接口I_Communication通过适配器FB_SerialComAdapterFB_SocketAdapter均可以正常工作,接口测试成功。

http://www.zskr.cn/news/5917.html

相关文章:

  • 深入浅出 Java 多线程:从线程生命周期到并发安全
  • 实用指南:LINUX910 CENTOS8 新建虚拟机;重设root密码/时间同步
  • 零基础学习PYthon记录
  • Grafana 中文入门教程 | 构建你的第一个仪表盘
  • Topaz Photo AI Pro 4.0.4 AI图片智能降噪
  • Edge浏览器网页长截图
  • C++多线程编程—线程控制、同步与互斥详解
  • mac 的任务栏 Windows-Style Taskbar For macOS
  • 快手Java一面
  • 想找Axure替代?这6个原型设计工具值得一试
  • 实用指南:javaweb HTML基本介绍/常见标签
  • 文档处理控件Aspose.Words教程:在 C# 中将 Markdown 转换为 PDF
  • docker容器mysql导入sql文件
  • IDE工具RAD Studio 13 Florence重磅发布:64 位 IDE + AI 组件全面升级!
  • 移动安全框架(MobSF)静态分析入门指南
  • CRMEB标准版PHP批量发货功能深度解析
  • 模型上下文协议(Model Context Protocol,MCP)
  • 大华设备视频平台EasyCVR视频分析设备平台双轨视频数据存储方案全解读
  • AI音乐创作新突破:ACE-Step模型开启放克音乐智能生成时代
  • macOS Sequoia 15.7 (24G222) Boot ISO 原版可引导镜像下载
  • Nginx 安装过程
  • mysql数据库服务主从复制实现(基于position)
  • 海量接入、毫秒响应:易易互联携手阿里云构筑高可用物联网消息中枢
  • C++ std::list
  • 能耐高温400度密封圈用什么材质
  • APDU笔记
  • CTFer
  • 聚焦实用:内外网文件摆渡系统品牌推荐来了!
  • MDI Jade9.0中文版详细下载及安装教程,附免费免激活版MDI Jade安装包!!
  • RC-Explainer | Reinforced Causal Explainer for Graph Neural Networks