說明

New features should be organised by feature/domain, not by technical layer. Each feature module contains its own controller, service, repository, and model classes.

Acceptable package patterns:

com.example.order/        ← feature module
  OrderController.java
  OrderService.java
  OrderRepository.java
  Order.java

com.example.inventory/    ← another feature module
  InventoryController.java
  InventoryService.java

為什麼重要

  • High cohesion — related code lives together
  • Low coupling — features communicate through well-defined interfaces
  • Team autonomy — different teams can own different feature modules

Enforcement

@ArchTest
static final ArchRule packageStructureRule = noClasses()
    .that().resideInAPackage("..controller..")
    .should().accessClassesThat().resideInAPackage("..repository..")
    .because("Controllers should only access their own feature's service layer");

正例

// com.example.order.OrderController
@RestController
public class OrderController {
    private final OrderService orderService; // ✅ same feature module
}

反例

// com.example.order.OrderController
@RestController
public class OrderController {
    private final InventoryService inventoryService; // ❌ cross-feature dependency
}