随着现代浏览器技术的飞速发展,在 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(成功)等)的抛出。
假设有一个库存检查的程序,如果检测到某个物品的库存数量低于设定值,我们需要抛出一个错误消息:
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 类型)可能允许用户选择是否继续执行操作。
对于交互式报表或事务代码中的程序,消息显示的方式尤为重要。正确的消息类型和合适的显示方式,可以有效地引导用户进行操作,提升用户体验。
实例分析
考虑到一个物料管理系统中的一个功能,需要根据物料编号获取物料描述,并检查物料库存。如果物料不存在或库存不足,系统需要分别给出不同的提示。
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 上:
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 支持广泛的编程构造,包括变量声明、控制流语句(如 if
、else
、for
循环)和自定义函数。
为了在 UI 上显示自定义消息,可以在 ABSL 脚本中使用 Messages
对象。这个对象提供了创建和管理消息的方法,包括错误消息、警告消息和信息消息。
我们以一个常见的需求为例来讲解具体的代码。假设我们需要在保存操作中抛出验证消息。
假设有一个自定义业务对象 MyCustomBO
,其中有一个字段 MyField
需要在保存时进行特定的验证。如果验证失败,应在 UI 上显示一条错误消息。
在 Cloud Application Studio 中,打开 MyCustomBO
的脚本文件,通常位于 Scripts
文件夹下的 AfterModify
事件中,添加如下 ABSL 代码:
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 架构的软件消息管理模块的设计与技术实现细节。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。