软件工程不只是写代码,而是一个从需求理解到生产运维的完整生命周期。在企业级 SAP 开发中,缺乏规范流程的项目往往导致代码质量差、维护成本高、上线风险大。本文从实践角度,系统梳理软件工程全生命周期的最佳实践,特别关注 SAP/ABAP 开发场景。
用户故事(User Story)是敏捷开发中表达需求的标准格式:
作为 [角色],我希望 [功能],以便 [价值]
示例:
作为 采购员,我希望 在审批被拒时收到邮件通知,以便 我能及时修改采购申请并重新提交。好的用户故事遵循 INVEST 原则:
每个用户故事必须定义验收标准(Acceptance Criteria),通常使用 Given-When-Then 格式:
Given 采购申请金额超过 10000 元
When 采购员提交申请
Then 申请自动路由至部门经理审批
Given 采购申请金额不超过 10000 元
When 采购员提交申请
Then 申请自动审批通过需求优先级常用 MoSCoW 方法:
| 优先级 | 含义 | 示例 |
|---|---|---|
| Must Have | 必须实现,否则系统无法上线 | 基本的采购订单创建流程 |
| Should Have | 重要但非关键,可延后一个 Sprint | 审批超时自动提醒 |
| Could Have | 锦上添花,时间允许才做 | 订单历史趋势图表 |
| Won't Have | 明确不在当前范围 | 移动端审批(Phase 2) |
领域驱动设计(Domain-Driven Design, DDD)强调以业务领域为中心进行软件设计,核心概念包括:
| 对比项 | 单体架构 | 微服务架构 |
|---|---|---|
| 开发效率 | 初期高,后期降低 | 初期低,后期稳定 |
| 部署复杂度 | 简单(一个部署单元) | 复杂(多个服务独立部署) |
| 技术栈灵活性 | 统一技术栈 | 每个服务可选不同技术栈 |
| 扩展性 | 整体扩展 | 按服务独立扩展 |
| 故障影响 | 局部故障可能拖垮整体 | 故障隔离在单个服务 |
| 数据一致性 | 强一致性(本地事务) | 最终一致性(分布式事务) |
| SAP 场景建议 | SAP 核心内的开发 | SAP BTP 上的扩展开发 |
SAP 场景的建议:SAP S/4HANA 核心系统本身是单体架构,不建议拆分。但在 SAP BTP 上构建扩展应用时,应采用微服务架构,每个扩展功能作为独立服务部署在 Cloud Foundry 或 Kyma 上。
SAP BTP 提供三种扩展模式:
| 扩展模式 | 适用场景 | 技术栈 | 部署环境 |
|---|---|---|---|
| In-App 扩展 | 轻量级 UI/逻辑调整 | SAP Fiori Embedding、Adobe Forms | S/4HANA 内部 |
| Side-by-Side 扩展 | 独立业务流程扩展 | Node.js / Java / Python | SAP BTP Cloud Foundry |
| Steampunk(ABAP Environment) | ABAP 开发者的云原生开发 | ABAP(云版本) | SAP BTP ABAP Environment |
Side-by-Side 扩展的典型架构:
Clean Code 的核心原则在所有编程语言中通用:
a1、temp、data 等模糊命名。代码审查(Code Review)是保障代码质量的核心实践:
SAP 官方发布的 ABAP Programming Guidelines 核心规则:
" 不推荐:过程式 + 旧语法
DATA: lt_mara TYPE STANDARD TABLE OF mara,
ls_mara TYPE mara.
SELECT * FROM mara INTO TABLE lt_mara WHERE matnr IN s_matnr.
LOOP AT lt_mara INTO ls_mara.
WRITE: / ls_mara-matnr.
ENDLOOP.
" 推荐:面向对象 + 新语法
SELECT matnr, ersda, matkl FROM mara
INTO TABLE @DATA(lt_mara)
WHERE matnr IN @s_matnr.
LOOP AT lt_mara INTO DATA(ls_mara).
cl_demo_output=>write( |物料: { ls_mara-matnr } 类型: { ls_mara-matkl }| ).
ENDLOOP.
cl_demo_output=>display( ).测试金字塔是测试策略的经典框架:
| 测试层级 | 数量占比 | 执行速度 | 覆盖范围 | SAP 实现方式 |
|---|---|---|---|---|
| 单元测试 | 70% | 毫秒级 | 单个方法/函数 | ABAP Unit(CL_AUNIT_ASSERT) |
| 集成测试 | 20% | 秒级 | 模块间交互 | 手动 / ECATT |
| E2E 测试 | 10% | 分钟级 | 端到端业务流程 | SAP CBTA / Selenium |
ABAP Unit 是 SAP 内置的单元测试框架,所有 ABAP 开发都应编写单元测试:
CLASS lcl_calculator DEFINITION.
PUBLIC SECTION.
METHODS: add IMPORTING iv_a TYPE i iv_b TYPE i
RETURNING VALUE(rv_result) TYPE i.
ENDCLASS.
CLASS lcl_calculator IMPLEMENTATION.
METHOD add.
rv_result = iv_a + iv_b.
ENDMETHOD.
ENDCLASS.
" 单元测试类
CLASS ltc_calculator DEFINITION FOR TESTING
RISK LEVEL HARMLESS DURATION SHORT.
PRIVATE SECTION.
METHODS: test_add FOR TESTING.
ENDCLASS.
CLASS ltc_calculator IMPLEMENTATION.
METHOD test_add.
DATA(lo_calc) = NEW lcl_calculator( ).
cl_abap_unit_assert=>assert_equals(
act = lo_calc->add( iv_a = 3 iv_b = 5 )
exp = 8
msg = '加法计算结果不正确' ).
ENDMETHOD.
ENDCLASS.在单元测试中,被测代码依赖的外部资源需要用测试替身替代:
在 ABAP 中,通过接口(INTERFACE)实现依赖注入,测试时注入 Mock 实现:
" 定义接口
INTERFACE lif_product_reader.
METHODS: get_product IMPORTING iv_matnr TYPE matnr
RETURNING VALUE(rs_product) TYPE mara.
ENDINTERFACE.
" 真实实现(从数据库读取)
CLASS lcl_product_reader_db DEFINITION.
PUBLIC SECTION.
INTERFACES: lif_product_reader.
ENDCLASS.
" 测试替身(返回预设数据)
CLASS lcl_product_reader_mock DEFINITION.
PUBLIC SECTION.
INTERFACES: lif_product_reader.
DATA: ms_stub_product TYPE mara.
ENDCLASS.持续集成(CI)确保每次代码变更都经过自动化验证,持续部署(CD)将通过验证的代码自动发布到目标环境:
| CI/CD 阶段 | ABAP 开发 | BTP 扩展开发 |
|---|---|---|
| 代码提交 | SAP Transport Request | Git Push / Pull Request |
| 自动构建 | abapGit / SAP ADT | npm / maven / pip build |
| 静态检查 | ATC(ABAP Test Cockpit) | ESLint / SonarQube |
| 单元测试 | ABAP Unit | JUnit / Jest / pytest |
| 集成测试 | eCatt | Postman / Newman |
| 部署 | 传输管理(STMS) | SAP BTP CLI / CF Push |
SAP 开发中的版本管理策略:
推荐的 Git 分支策略(适用于 BTP 扩展开发):
结构化日志是运维可观测性的基础:
BAL_LOG_CREATE / BAL_LOG_MSG_ADD 写入应用日志(SLG1 查看),而非 WRITE 语句。关键指标的告警设置:
| 监控指标 | 告警阈值 | 检查方式 |
|---|---|---|
| SAP 系统响应时间 | 平均 > 2 秒 | ST03N 工作负载监控 |
| 后台作业失败率 | 日失败 > 5% | SM37 作业监控 |
| 数据库 CPU 利用率 | 持续 > 80% | DBACOCKPIT |
| 短转储(Dump)数量 | 日新增 > 10 个 | ST22 转储分析 |
| BTP 应用实例状态 | 实例 Down | BTP Cockpit / Prometheus |
| 接口调用失败率 | 日失败 > 1% | SAP Integration Suite 监控 |
建立性能基线(Baseline)是发现性能退化的关键: