如何定义Archunit兜底层级,无需因新增模块更新配置?
解决Archunit分层测试中Rest层无需手动更新的问题
针对你的需求,完全可以把Rest层定义为除其他指定层之外的所有内容,同时还有更省心的分层策略可选,具体方案如下:
方案一:动态排除所有明确定义的层
先把所有需要独立管控的层(比如newModule、common、apiclient,未来新增的模块也归到这类)的条件单独提取出来,然后Rest层直接定义为根包下不属于这些层的所有内容。这样未来新增模块时,只需要添加对应模块的条件,无需修改Rest层的定义。
示例代码:
// 提取各明确层的条件 ArchCondition<Object> newModuleCondition = resideInAPackage("org.mycompany.newmodule.."); ArchCondition<Object> commonCondition = resideInAPackage("org.mycompany.common.."); ArchCondition<Object> apiClientCondition = resideInAPackage("org.mycompany.apiclient.."); // 未来新增模块时,只需在这里追加or(新模块Condition)即可 ArchCondition<Object> allExplicitLayers = newModuleCondition.or(commonCondition).or(apiClientCondition); ArchRule architectureRule = layeredArchitecture() .consideringOnlyDependenciesInAnyPackage("org.mycompany..") .layer("newModule").definedBy(newModuleCondition) .layer("common").definedBy(commonCondition) .layer("apiclient").definedBy(apiClientCondition) // Rest层自动匹配根包下不属于任何明确层的内容 .layer("rest").definedBy(resideInAPackage("org.mycompany..").and(not(allExplicitLayers))) .whereLayer("newModule").mayNotBeAccessedByAnyLayer() .whereLayer("newModule").mayOnlyAccessLayers("common", "apiclient");
方案二:按包结构统一归类功能模块
如果你的项目模块命名有统一规范(比如所有业务模块都是org.mycompany.xxx..的直接子包,而common、apiclient、rest是全局通用包),可以把所有业务模块归为一类,统一设置规则,未来新增模块只要符合包结构就自动纳入管控,完全不用修改测试代码。
示例代码:
// 定义所有业务模块的通用条件:根包下的直接子包,但排除common、apiclient、rest ArchCondition<Object> featureModulesCondition = resideInAPackage("org.mycompany.*..").and( not(resideInAPackage("org.mycompany.common..")) .and(not(resideInAPackage("org.mycompany.apiclient.."))) .and(not(resideInAPackage("org.mycompany.rest.."))) ); ArchRule architectureRule = layeredArchitecture() .consideringOnlyDependenciesInAnyPackage("org.mycompany..") .layer("featureModules").definedBy(featureModulesCondition) .layer("common").definedBy("org.mycompany.common..") .layer("apiclient").definedBy("org.mycompany.apiclient..") .layer("rest").definedBy("org.mycompany.rest..") // 所有业务模块统一应用规则:不被任何层访问,仅依赖common和apiclient .whereLayer("featureModules").mayNotBeAccessedByAnyLayer() .whereLayer("featureModules").mayOnlyAccessLayers("common", "apiclient");
两种方案都能满足你的核心需求:确保目标模块仅依赖指定层且不被其他代码访问,同时大幅降低未来新增模块时的测试代码维护成本。
内容的提问来源于stack exchange,提问作者freafrea
相关产品推荐
相关产品推荐

