关于 clean-abap
clean-abap 是一项按 Clean ABAP 原则检查 ABAP 代码的技能。它按主题整理问题、标注影响级别,并提供带代码示例的改进建议。
主要功能
- 01检查 15 类 Clean ABAP 规范
- 02按主题归类问题
- 03按影响程度确定优先级
- 04提供代码示例和修正建议
- 05参考附带的风格指南
适用场景
- 01检查 ABAP 代码风格问题
- 02发现过时的 ABAP 语言模式
- 03改进命名与方法设计
- 04评估可测试性和错误处理
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ likweitan/ abap-skills --skill clean-abap安装后在 Claude Code 中输入/clean-abap确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/checklist.mdCleanABAP.mdquick-reference.md详细介绍
Clean ABAP
此技能依据 Clean ABAP 风格指南,对照其中的原则全面检查 ABAP 代码。该指南将 Robert C. Martin 的 Clean Code 原则应用于 ABAP。
如何使用此技能
检查 ABAP 代码是否符合 Clean ABAP 规范时:
- 阅读用户提供的代码
- 按 Clean ABAP 章节对问题进行分类(名称、语言、常量、变量、表、字符串、布尔值、条件、IF 语句、类、方法、错误处理、注释、格式、测试)
- 在条件允许时,指出违规之处并提供具体行号
- 提供可执行的改进建议,并通过代码示例展示问题和整洁的解决方案
- 按影响程度对问题进行优先级排序(严重、主要、次要)
检查类别
1. 名称
核心原则:
- 使用能表达内容和含义的描述性名称
- 优先使用解决方案领域和问题领域中的术语
- 使用易于发音的名称
- 始终使用 snake_case
- 除非必要,否则避免缩写
- 类使用名词,方法使用动词
- 避免在名称中使用 "data"、"info"、"object" 等无意义词语
- 为每个概念选用一个词
- 避免编码式命名(匈牙利命名法,以及 iv*、rv*、lt_ 等前缀)
- 避免使用容易与内置函数混淆的名称
检查以下问题:
- 变量、方法或类的名称缺乏描述性(例如,
data1、temp、x) - 代码中缩写使用不一致
- 命名风格混用(未采用 snake_case)
- 名称中包含无意义词语
- 使用匈牙利命名法或不必要的前缀(iv*、ev*、rv*、lt*、ls_)
- 方法名称容易与 ABAP 内置函数混淆
2. 语言
核心原则:
- 面向对象编程优于过程式编程
- 函数式语言结构优于过程式语言结构
- 避免使用过时的语言元素
- 合理使用设计模式
检查以下问题:
- 使用过时语句(如 SELECT 中未转义的宿主变量等)
- 本应采用面向对象方式实现的过程式代码
- 使用旧式 MOVE,而非赋值
- 使用 TRANSLATE,而非 to_upper()/to_lower()
- 使用 CREATE OBJECT,而非 NEW
- 使用旧式 READ TABLE,而非表表达式
3. 常量
核心原则:
- 使用常量代替魔法数字
- 常量应使用描述性名称
- 优先使用 ENUM,而非常量接口
- 将相关常量归组
检查以下问题:
- 代码中出现魔法数字或字符串字面量
- 常量名称缺乏描述性(c_01、c_x 等)
- 未归组的常量本应放在 BEGIN OF/END OF 块中
4. 变量
核心原则:
- 优先使用内联声明,而非预先声明
- 不要在声明块之外使用变量
- 不要链式预先声明
- 现代 ABAP 中不要使用字段符号动态访问数据
- 选择合适的循环目标(字段符号、引用或值)
检查以下问题:
- 使用预先 DATA 声明,而内联声明会更清晰
- 在声明块作用域之外使用变量
- 链式 DATA 声明
- 使用 ASSIGN 时存在不必要的字段符号
5. 表
核心原则:
- 使用合适的表类型(STANDARD、SORTED、HASHED)
- 避免使用 DEFAULT KEY
- 优先使用 INSERT INTO TABLE,而非 APPEND TO
- 优先使用 LINE_EXISTS,而非 READ TABLE 或 LOOP AT
- 优先使用 READ TABLE,而非 LOOP AT
- 优先使用 LOOP AT WHERE,而非嵌套 IF
- 避免不必要的表读取
检查以下问题:
- 表使用 DEFAULT KEY
- 在 INSERT INTO TABLE 更合适时使用 APPEND TO
- 使用 READ TABLE ... TRANSPORTING NO FIELDS,而 LINE_EXISTS 会更清晰
- 使用 LOOP AT ... EXIT,而实际意图是 READ TABLE
- LOOP AT 内嵌套 IF,而 WHERE 子句即可实现
- 重复读取(先检查是否存在,随后再次读取)
6. 字符串
核心原则:
- 使用 `(反引号)定义字符串字面量
- 使用 |(管道符)拼接文本
检查以下问题:
- 使用单引号表示字符串字面量
- 使用 && 拼接字符串,而非字符串模板
7. 布尔值
关键原则:
- 布尔类型使用 ABAP_BOOL
- 比较时使用 ABAP_TRUE 和 ABAP_FALSE
- 使用 XSDBOOL 设置布尔变量
- 考虑布尔值是否合适(与枚举相比)
检查项:
- 使用 CHAR1 或其他类型代替 ABAP_BOOL
- 使用 'X' 和 ' ' 比较,而不是 ABAP_TRUE/ABAP_FALSE
- 使用 IF-THEN-ELSE 设置布尔值,而不是 XSDBOOL
- 应拆分为多个方法的布尔参数
8. 条件
关键原则:
- 尽量使用肯定条件
- 优先使用 IS NOT,而不是 NOT IS
- 对于返回布尔值的方法,考虑使用谓词式调用
- 考虑分解/提取复杂条件
检查项:
- 可以改为肯定条件的否定条件
- 使用 NOT IS,而不是 IS NOT
- 应当分解的复杂嵌套条件
- 应当提取到方法中的冗长条件
9. If 语句
关键原则:
- 不要有空的 IF 分支
- 有多个选项时,优先使用 CASE,而不是 ELSE IF
- 尽量减少嵌套层级
检查项:
- 仅在 ELSE 中包含逻辑的空 IF
- 应改为 CASE 的多个 ELSE IF
- 嵌套过深的 IF 语句(>3 层)
10. 类
关键原则:
- 优先使用对象,而不是静态类
- 优先使用组合,而不是继承
- 不要在同一个类中混用有状态和无状态逻辑
- 默认使用全局类,仅在合适时使用本地类
- 如果类并非为继承而设计,则使用 FINAL
- 成员默认设为 PRIVATE,仅在需要时使用 PROTECTED
- 考虑使用不可变数据代替 getter
检查项:
- 应基于实例而非静态的类
- 过深的继承层次结构
- 混用有状态和无状态方法
- 并非为继承而设计但未设为 FINAL 的类
- 应设为 PRIVATE/PROTECTED 的 PUBLIC 成员
- 获取不可变数据的不必要 getter 方法
11. 方法
关键原则:
- 优先使用实例方法,而不是静态方法
- 公有实例方法应实现接口
- 尽量减少 IMPORTING 参数(<3 个)
- 拆分方法,而不是使用 OPTIONAL 参数
- 恰好使用一个 RETURN、EXPORT 或 CHANGE 参数
- 优先使用 RETURNING,而不是 EXPORTING
- 只做一件事,并把它做好
- 保持方法简短(理想情况下为 3-5 条语句)
- 尽早失败
- 尽可能省略 RECEIVING、EXPORTING 关键字
- 调用实例成员时省略自引用 ME
检查项:
- 应改为实例方法的静态方法
- 不属于接口的公有方法
- IMPORTING 参数超过 3 个的方法
- 多个 OPTIONAL 参数(应拆分方法)
- 多个输出参数
- 使用 EXPORTING,而不是 RETURNING
- 过长的方法(>20 行)
- 执行多项任务的方法
- 不必要的 RECEIVING、EXPORTING 关键字
- 显式 ME-> 调用
12. 错误处理
关键原则:
- 优先使用异常,而不是返回码
- 使用基于类的异常
- 可处理的异常抛出 CX_STATIC_CHECK
- 不可恢复的情况抛出 CX_NO_CHECK
- 优先使用 RAISE EXCEPTION NEW,而不是 RAISE EXCEPTION TYPE
- 包装外部异常
检查项:
- 使用返回码,而不是异常
- 使用消息类处理错误
- 使用旧式的 RAISE EXCEPTION TYPE
- 未包装的外部异常
- 捕获通用的 CX_ROOT
13. 注释
关键原则:
- 用代码表达意图,而不是注释
- 不要用注释为糟糕的命名开脱
- 写注释解释原因,而不是内容
- 注释使用 ",而不是 *
- 删除代码,而不是将其注释掉
- 使用 FIXME、TODO、XXX 时附上你的 ID
- ABAP Doc 仅用于公有 API
检查项:
- 解释代码作用的显而易见的注释
- 用注释弥补糟糕的命名
- 被注释掉的代码
- 使用 - 注释,而不是 "
- 不带 TODO/FIXME 标签的注释
- 注释中的手动版本管理
- 注释中重复的消息文本
14. 格式
核心原则:
- 激活前使用 ABAP Formatter
- 每行最多一条语句
- 行长适中(120 个字符)
- 用单个空行分隔(不多于一个)
- 在行尾闭合括号
- 单参数调用保持在一行内
- 缩进并对齐到制表符
检查以下内容:
- 每行包含多条语句
- 行长超过 120 个字符
- 存在多个连续空行
- 缩进不一致
- 链式赋值
15. 测试
核心原则:
- 编写可测试的代码
- 测试公有部分,而非私有内部实现
- 使用 given-when-then 结构
- 断言数量少且聚焦
- 使用恰当的断言类型
检查以下内容:
- 代码不可测试(耦合紧密、未使用依赖注入)
- 测试缺少清晰的 given-when-then 结构
- 存在多个无关的断言
- 公有方法缺少测试类
输出格式
按以下结构组织分析:
# Clean ABAP Check Results
## Summary
- Total Issues: [count]
- Critical: [count]
- Major: [count]
- Minor: [count]
## Critical Issues
### [Category] - [Issue Title]
**Location:** Line [X] / Method [name]
**Problem:** [Description of what violates Clean ABAP]
**Recommendation:** [How to fix it]
**Anti-pattern:**
```abap
[problematic code]
整洁代码:
[improved code]
重大问题
[与“严重问题”格式相同]
次要问题
[与“严重问题”格式相同]
优点观察
- [符合 Clean ABAP 的良好做法]
总体评估
[简要总结代码质量和主要改进领域]
## Priority Levels
**Critical:** Issues that significantly impact maintainability, testability, or could cause bugs
- Magic numbers without constants
- Deep nesting (>3 levels)
- Methods with >5 parameters
- Empty IF branches
- Static classes without interfaces
- Return codes instead of exceptions
**Major:** Issues that reduce code clarity and violate Clean ABAP principles
- Non-descriptive names
- Hungarian notation/prefixes
- Long methods (>20 lines)
- DEFAULT KEY usage
- Commented-out code
- Multiple output parameters
**Minor:** Issues that are stylistic improvements
- Missing inline declarations
- String quotes instead of backticks
- Unnecessary ME-> references
- Formatting inconsistencies
## References
When you need detailed explanations or examples for specific Clean ABAP rules, consult these reference files:
1. **Complete Guidelines**: Read `references/CleanABAP.md` - the full Clean ABAP style guide with in-depth explanations, rationale, and code examples for all principles
2. **Quick Patterns**: Read `references/quick-reference.md` - condensed good/bad code examples for common patterns
3. **Review Checklist**: Read `references/checklist.md` - a checklist format for systematic code reviews
**When to consult references:**
- To provide accurate citations when explaining violations
- To show users the official reasoning behind recommendations
- To find specific code examples to illustrate points
- To answer follow-up questions about Clean ABAP principles
- When encountering edge cases not covered in the summary above
## Examples
### Example 1: Checking a Simple Method
**Input:**
```abap
METHOD calculate.
DATA: lv_result TYPE i,
lv_temp TYPE i.
lv_temp = iv_value1 + iv_value2.
IF lv_temp > 100.
lv_result = lv_temp * 2.
ELSE.
lv_result = lv_temp.
ENDIF.
ev_result = lv_result.
ENDMETHOD.
输出:
# Clean ABAP Check Results
## Summary
- Total Issues: 4
- Critical: 0
- Major: 2
- Minor: 2
## Major Issues
### Names - Hungarian Notation Used
**Location:** Method calculate
**Problem:** Variables use Hungarian notation prefixes (lv_, iv_, ev_) which adds no value and violates Clean ABAP naming guidelines.
**Recommendation:** Remove prefixes and use descriptive names.
**Anti-pattern:**
```abap
DATA: lv_result TYPE i,
lv_temp TYPE i.
整洁代码:
DATA(result) = value1 + value2.
IF result > 100.
result = result * 2.
ENDIF.
方法——使用 EXPORTING 而非 RETURNING
位置: 方法签名 问题: 方法使用 EXPORTING 参数而非 RETURNING,无法采用函数式调用风格。 建议: 对单个输出值使用 RETURNING 参数。
反模式:
METHOD calculate
IMPORTING iv_value1 TYPE i
iv_value2 TYPE i
EXPORTING ev_result TYPE i.
整洁代码:
METHOD calculate
IMPORTING value1 TYPE i
value2 TYPE i
RETURNING VALUE(result) TYPE i.
次要问题
变量——提前声明
位置: 第 2-3 行 问题: 变量提前声明,导致声明与使用之间间隔较远。 建议: 使用 DATA( ) 进行内联声明。
语言——过程式风格
位置: 第 5-9 行 问题: 可以使用 COND 进行条件赋值,而非 IF-ELSE。 建议: 使用函数式结构。
整洁代码:
METHOD calculate
IMPORTING value1 TYPE i
value2 TYPE i
RETURNING VALUE(result) TYPE i.
DATA(sum) = value1 + value2.
result = COND #( WHEN sum > 100 THEN sum * 2 ELSE sum ).
ENDMETHOD.
总体评估
代码可以正常运行,但使用了过时的 ABAP 模式。主要改进方向:移除匈牙利命名法,使用 RETURNING 代替 EXPORTING,优先采用内联声明,并使用函数式语言结构。完成这些更改后,代码将更加整洁且易于维护。