如何编写ArchUnit规则,确保仅公开常量字段、其余字段均为私有
如何编写ArchUnit规则,确保仅公开常量字段、其余字段均为私有
我完全懂你遇到的困扰——你最初写的规则太“一刀切”了,把枚举里的枚举常量还有合法的public static final常量都误判成了违规项,对吧?别着急,我们可以调整ArchUnit的规则逻辑,精准区分允许公开的常量和必须私有化的普通字段。
先说说问题出在哪:枚举里的每个枚举值(比如你例子里的IOS、LAPTOP)本质上是**public static final的枚举类实例**,而你的初始规则要求所有字段必须是private,自然会把这些合法的枚举常量标记为违规。同时,你原本想允许的public static final常量也会被错误拦截。
接下来给你两个可行的解决方案,按需选择:
方案一:允许所有public static final字段,其余必须私有
这个方案最直接,完全符合你最初的需求——只要是public static final的字段(包括枚举常量、普通常量)都允许,其他字段必须是private:
import static com.tngtech.archunit.core.domain.JavaModifier.*; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields; import static com.tngtech.archunit.lang.syntax.Conditions.be; @Test void fieldsMustBePrivateOrPublicStaticFinal() { fields() .should(be(PRIVATE).or(be(PUBLIC).and(be(STATIC).and(be(FINAL))))) .because("Only public static final constants are allowed to be public; all other fields must be private") .check(importedClasses); }
这样修改后,枚举类的字段不会再被误判,合法的常量也能正常通过检查。
方案二:更严格的常量校验(可选)
如果你想进一步限制“允许公开的常量”只能是基本类型或字符串(排除枚举实例这类对象类型),可以给规则加上类型判断:
import static com.tngtech.archunit.core.domain.JavaModifier.*; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields; import static com.tngtech.archunit.lang.syntax.Conditions.*; @Test void fieldsMustBePrivateOrPublicPrimitiveOrStringConstants() { fields() .should(be(PRIVATE) .or(allOf( be(PUBLIC), be(STATIC), be(FINAL), field -> field.getType().isPrimitive() || field.getType().isAssignableTo(String.class) ))) .because("Only public static final primitive/String constants are allowed; all other fields must be private") .check(importedClasses); }
这个版本会拦截枚举的公开字段,如果你的业务场景不希望枚举字段被当成“合法公开常量”,可以用这个规则。
备注:内容来源于stack exchange,提问作者PatPanda
相关产品推荐
相关产品推荐

