You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一模块内App/Foo/Bar架构层的依赖限制实现方法问询

Awesome question! It's totally possible to enforce those clean dependency boundaries within a single module without splitting into separate submodules or messing with Gradle dependencies. Here are a few practical, actionable approaches:

1. Language Access Modifiers (Foundation Layer)

Start with basic language-level access controls to lay a groundwork for your rules. This won't cover every restriction on its own, but it's a great starting point:

For Java Projects

  • Bar Layer: Make all Bar classes public so both App and Foo layers can access them. Since Bar shouldn't reference App/Foo types, any accidental imports will either fail to compile (if App/Foo types are non-public) or be caught by additional checks later.
  • Foo Layer: Expose only the classes/methods the App needs as public. Keep internal Foo utilities as package-private (no access modifier) to block Bar from accessing them. Note: Public Foo classes will still be visible to Bar, so we'll need extra checks here.
  • App Layer: Mark all App-specific classes as package-private. This instantly blocks Foo and Bar from accessing App layer code (since they're in separate packages), perfectly enforcing the "App → Foo/Bar only" rule in reverse.

For Kotlin Projects

  • Bar Layer: Use Kotlin's default public visibility for Bar classes so App/Foo can access them. Avoid referencing App/Foo types—if you mark App/Foo's internal types as internal, Kotlin's compiler will throw errors if Bar tries to access them (though internal is module-wide, so we'll pair this with other tools to lock it down).
  • Foo Layer: Use public for classes the App needs, and internal for internal implementation details.
  • App Layer: Since Kotlin doesn't have package-private, mark App classes as internal and use static analysis tools (see below) to restrict which packages can access them.
2. ArchUnit (Full Build-Time Enforcement)

ArchUnit is a powerful static analysis tool that lets you define and enforce architectural rules directly in your code. It works for both Java and Kotlin, runs as part of your build, and catches any accidental cross-layer references.

Here's how to set it up:

  1. Add ArchUnit to your module's build dependencies (no separate modules needed—just add it to your existing Gradle/Maven config).
  2. Create a test class (e.g., ModuleArchitectureTest) to define your rules:
    @AnalyzeClasses(packages = "com.yourpackage.yourmodule")
    public class ModuleArchitectureTest {
        // Rule 1: Bar layer cannot access App or Foo layers
        @ArchTest
        public static final ArchRule bar_cannot_access_others = noClasses()
            .that().resideInAPackage("..bar..")
            .should().accessClassesThat().resideInAnyPackage("..app..", "..foo..");
    
        // Rule 2: Foo layer can only access Bar (no App access)
        @ArchTest
        public static final ArchRule foo_only_accesses_bar = noClasses()
            .that().resideInAPackage("..foo..")
            .should().accessClassesThat().resideInAPackage("..app..");
    
        // Optional: Explicitly document App's allowed dependencies
        @ArchTest
        public static final ArchRule app_can_access_foo_bar = classes()
            .that().resideInAPackage("..app..")
            .should().onlyAccessClassesThat().resideInAnyPackage("..app..", "..foo..", "..bar..");
    }
    
  3. Run the test—any violations (like Bar referencing a Foo class) will fail the build, strictly enforcing your dependency rules.

This is the most reliable way to lock down all your boundaries, as it catches edge cases that language modifiers might miss.

3. IDE-Level Checks (Real-Time Feedback)

Pair the above with IDE settings to get immediate feedback while coding:

  • IntelliJ IDEA/Android Studio: Use the Structure Search and Replace tool to create custom inspections that flag forbidden cross-package references. For example, set up an inspection that triggers when a class in ..bar.. imports a class from ..foo...
  • Use the built-in Dependency Analyzer (under View > Tool Windows > Dependency Analyzer) to visualize cross-package dependencies and spot violations early.

内容的提问来源于stack exchange,提问作者Martin Mlostek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:23:12