聊聊基于传统 Client 、Server 架构的企业级软件中的消息显示机制的实现

随着现代浏览器技术的飞速发展,在 2C 领域的应用设计,越来越多的从传统的 Client/Server 即 C/S 架构,迁移到了 Browser/Server 这种 B/S 架构上来。然而在企业级软件领域,还是有不少软件,特别是企业管理软件,比如 ERP(Enterprise Resource Planning),MRP(Material Requirement Planning),MES(Manufacturing Execution System)等等,仍然采取的是传统的 Client/Server 架构。

C/S 模式是一种成熟且广泛应用的软件架构模式,它通过将应用程序分为客户端和服务器两部分,实现了功能的分工和专业化,提高了应用程序的效率、可扩展性和安全性。尽管 C/S 模式存在一些挑战,比如服务器的性能和稳定性问题,但通过精心设计和管理,这些挑战是可以克服的。

笔者从事 C/S 模式下的企业级软件开发多年,也积累了一些实战经验。本文聊聊笔者曾经参与过的 C/S 模式下软件中消息显示机制的设计与实现的一些话题。

消息是应用程序执行过程中给用户提供反馈的重要渠道之一,通常由用户某个动作直接触发,显示在产品界面上。当然应用程序后台作业运行到某个阶段,在满足指定条件时也能触发消息显示。简明、清晰而准确的消息,能帮助用户明确程序当前的运行状况,指引其下一步的操作。

在企业级软件领域,产品 UI 显示的消息文本,一般都有专业的 Knowledge Management 即 KM 团队负责审查和发布。

对于软件开发人员来说,更关心的则是这些消息显示的上下文;换言之,看到 UI 上显示一条消息之后,能否在最短的时间内,高效定位到抛出该消息的准确代码位置。

我们下面通过一些业界普遍认可的企业级管理软件的消息显示设计,来提炼出一些优秀的设计共性。 如下图所示,在经典的 Netweaver SE38 ABAP 程序编辑器,输入一个不存在的报表名称,会显示一条消息:

Program XX does not exist.

其中 XX 是占位符,会被用户实际输入的报表名称所替换。

基于 ABAP 实现的所有 SAP 产品,比如 SAP CRM,SAP SRM,SAP S/4HANA,SAP Cloud for Customer,UI 上显示的每一条消息,在 ABAP 后台均有一条对应的消息记录,维护在事物码 SE91 里。

以上图的消息为例,其号码为 DS017,其中 DS 为消息类别, 017 为消息编号,二者唯一确认一条消息记录。

在 SAP 系统中,消息被组织在消息类中,每个消息类包含多个消息,每个消息通过一个唯一的数字(通常是三位数)进行标识。消息文本可以包含占位符(如 &&1&2 等),在实际抛出消息时,这些占位符会被替换成具体的值。

例如,如果我们有一个消息类 ZMY_MESSAGES,其中定义了一个消息 001,其文本为:库存不足,当前库存数量为 &

抛出消息

在 ABAP 程序中,可以使用 MESSAGE 语句抛出一个消息。MESSAGE 语句有多种形式,根据不同的需要,可以实现不同类型的消息(如 E(错误)、W(警告)、I(信息)、S(成功)等)的抛出。

假设有一个库存检查的程序,如果检测到某个物品的库存数量低于设定值,我们需要抛出一个错误消息:

sql 复制代码
DATA: lv_stock_qty TYPE i VALUE 5.

IF lv_stock_qty < 10.
  MESSAGE e001(`ZMY_MESSAGES`) WITH lv_stock_qty DISPLAY LIKE 'E'.
ENDIF.

在这个例子中,e001 表示使用消息类 ZMY_MESSAGES 中编号为 001 的消息,消息类型为 E(错误)。WITH 关键字后面跟着的是要替换消息文本中占位符的实际值。DISPLAY LIKE 'E' 指定了消息的显示类型,即以错误消息的形式显示。

消息显示

在 ABAP 程序中,抛出的消息会根据其类型和上下文以不同的方式显示给用户。例如,错误消息(E 类型)通常会导致程序运行被终止,并在状态栏或弹出窗口中显示错误信息。而警告消息(W 类型)可能允许用户选择是否继续执行操作。

对于交互式报表或事务代码中的程序,消息显示的方式尤为重要。正确的消息类型和合适的显示方式,可以有效地引导用户进行操作,提升用户体验。

实例分析

考虑到一个物料管理系统中的一个功能,需要根据物料编号获取物料描述,并检查物料库存。如果物料不存在或库存不足,系统需要分别给出不同的提示。

sql 复制代码
DATA: lv_matnr TYPE matnr,
      lv_description TYPE maktx,
      lv_stock_qty TYPE i,
      lv_matnr_not_found TYPE abap_bool VALUE abap_false,
      lv_stock_insufficient TYPE abap_bool VALUE abap_false.

lv_matnr = '0000000001'. " 假设这是用户输入的物料编号

" 查询物料描述
SELECT SINGLE maktx INTO lv_description FROM mara WHERE matnr = lv_matnr.
IF sy-subrc <> 0.
  lv_matnr_not_found = abap_true.
ENDIF.

" 检查库存数量
IF NOT lv_matnr_not_found.
  SELECT SINGLE labst INTO lv_stock_qty FROM marc WHERE matnr = lv_matnr.
  IF lv_stock_qty < 10.
    lv_stock_insufficient = abap_true.
  ENDIF.
ENDIF.

" 根据检查结果抛出消息
IF lv_matnr_not_found.
  MESSAGE s002(`ZMY_MESSAGES`) WITH lv_matnr DISPLAY LIKE 'S'.
ELSEIF lv_stock_insufficient.
  MESSAGE i003(`ZMY_MESSAGES`) WITH lv_matnr lv_stock_qty DISPLAY LIKE 'I'.
ELSE.
  MESSAGE s004(`ZMY_MESSAGES`) WITH lv_matnr lv_description lv_stock_qty DISPLAY LIKE 'S'.
ENDIF.

在这个例子中,通过不同的 MESSAGE 语句抛出了不同类型的消息,包括物料不存在的成功消息(S 类型),库存不足的信息消息(I 类型),以及物料和库存检查均正常的成功消息(S 类型)。每个 MESSAGE 语句都携带了相应的数据,用于替换消息文本中的占位符,以向用户提供详细的反馈信息。

到了 SAP CRM WebClient UI 里,浏览器上看到的每一条消息,比如下图 Data Contains errors and cannot be saved, 仍然唯一对应后台一条消息记录 CRM_BUPA_BOL/036:

这条消息是由 Business Partner 应用负责维护的。

到了 SAP Cloud for Customer,虽然 Partners 无法直接登录 ABAP 后台,然而仍然可以通过 Chrome 开发者工具,得到 UI 消息对应的 ABAP 后台消息记录的消息类和消息编号:

在 SAP Cloud for Customer 里,Partners 可以通过 Cloud Application Studio 新建 UI 消息:

在 ABSL 代码里,通过 raise 语句显示消息到 UI 上:

javascript 复制代码
raise delivery_message.Create("S", this.OutboundDeliveryID);

运行时 delivery_message 定义的消息文本里的 &1,会被 this.outboundDeliveryID 字段的值取代。

我们上面看到的是 SAP C4C 提供的一套强大的定制开发工具 ------ Cloud Application Studio 和一种专门的脚本语言 ------ ABSL (Advanced Business Scripting Language)。通过这些工具,开发人员可以在 SAP C4C 中创建和部署自定义应用程序、业务逻辑和用户界面元素。

通过 Cloud Application Studio 和 ABSL 进行消息的抛出和显示的详细步骤如下:

使用 Cloud Application Studio 开发自定义功能的第一步是创建一个新的解决方案。解决方案是包含一个或多个自定义开发项目的容器。在 Cloud Application Studio 中,选择 文件 > 新建 > 解决方案,填写必要的信息,如解决方案名称、描述和命名空间。

在解决方案中,可以定义一个或多个自定义业务对象(BO)。这些对象用于存储和管理与特定业务流程相关的数据。在 Cloud Application Studio 中,右键点击解决方案,选择 添加 > 新对象 > 业务对象,并定义业务对象的结构,包括字段和关联。

在自定义业务对象创建后,可以为其编写自定义逻辑,使用 ABSL 编程语言实现特定的业务需求。ABSL 支持广泛的编程构造,包括变量声明、控制流语句(如 ifelsefor 循环)和自定义函数。

为了在 UI 上显示自定义消息,可以在 ABSL 脚本中使用 Messages 对象。这个对象提供了创建和管理消息的方法,包括错误消息、警告消息和信息消息。

我们以一个常见的需求为例来讲解具体的代码。假设我们需要在保存操作中抛出验证消息。

假设有一个自定义业务对象 MyCustomBO,其中有一个字段 MyField 需要在保存时进行特定的验证。如果验证失败,应在 UI 上显示一条错误消息。

在 Cloud Application Studio 中,打开 MyCustomBO 的脚本文件,通常位于 Scripts 文件夹下的 AfterModify 事件中,添加如下 ABSL 代码:

javascript 复制代码
if (this.MyField.IsInitial()) {
    var message = "MyField 不允许为空,请输入值。";
    Messages.CreateErrorMessage(message);
}

这段代码检查 MyField 是否为空。如果为空,则使用 Messages.CreateErrorMessage 方法创建一条错误消息,消息内容为 MyField 不允许为空,请输入值。。当用户尝试保存 MyCustomBO 对象而没有为 MyField 提供值时,这条错误消息会显示在 UI 上,提醒用户需要填写该字段。

下面需要将上述消息,在 UI 上显示出来。

SAP C4C 的 UI 组件能够自动捕捉到通过 ABSL 脚本抛出的消息,并将其显示在适当的位置,通常是表单的顶部或字段旁边。无需进行额外的 UI 开发工作来实现消息的显示。

在完成开发后,可以在 Cloud Application Studio 中测试自定义功能。测试无误后,将解决方案部署到 SAP C4C 系统中,以供最终用户使用。

总结

本文以 ABAP Netweaver,WebClient UI 和 Cloud for Customer 这几款业界知名的企业级软件中,消息的设计和抛出机制为例,介绍了基于 Client / Server 架构的软件消息管理模块的设计与技术实现细节。

相关推荐
coderSong256816 分钟前
Java高级 |【实验八】springboot 使用Websocket
java·spring boot·后端·websocket
Mr_Air_Boy1 小时前
SpringBoot使用dynamic配置多数据源时使用@Transactional事务在非primary的数据源上遇到的问题
java·spring boot·后端
打码人的日常分享2 小时前
物联网智慧医院建设方案(PPT)
大数据·物联网·架构·流程图·智慧城市·制造
咖啡啡不加糖2 小时前
Redis大key产生、排查与优化实践
java·数据库·redis·后端·缓存
白水baishui2 小时前
搭建强化推荐的决策服务架构
架构·推荐系统·强化学习·决策服务·服务架构
何双新2 小时前
第23讲、Odoo18 邮件系统整体架构
ai·架构
雪碧聊技术2 小时前
将单体架构项目拆分成微服务时的两种工程结构
微服务·架构·module·project·工程结构
大鸡腿同学3 小时前
纳瓦尔宝典
后端
从零开始学习人工智能3 小时前
Doris 数据库深度解析:架构、原理与实战应用
数据库·架构