Organizing Code Structure

1. Designing Package Structure

StrategyProsCons
By layerFamiliar, simpleCross-cuts feature changes
By featureCohesive, scalesLearning curve
HexagonalClear boundariesInitial complexity
com.acme.order/
  domain/      Order, OrderStatus, OrderRepository (port)
  application/ PlaceOrderService
  adapters/in/  OrderController
  adapters/out/ JpaOrderRepository (adapter)
  

2. Implementing Layered Architecture

LayerDepends OnKnows About
PresentationApplicationHTTP, JSON
ApplicationDomainUse cases
DomainNothingBusiness rules
InfrastructureDomain (impl)DB, MQ, HTTP clients
Warning: Domain must never import infrastructure or framework types.

3. Implementing Module Boundaries

ToolMechanism
Java Modulesmodule-info.java exports
Maven/Gradle modulesCompile-time isolation
ArchUnitRuntime architecture tests
Package-privateHide implementation classes

4. Organizing Code by Features

Example: Feature packages

com.acme/
  user/    User, UserService, UserController, UserRepository
  order/   Order, OrderService, OrderController, OrderRepository
  shared/  cross-cutting utilities
BenefitDetail
LocalityOne feature, one place
DeleteRemove a feature = remove a folder

5. Organizing Code by Layers

Example: Layer packages

com.acme/
  controller/  UserController, OrderController
  service/     UserService, OrderService
  repository/  UserRepository, OrderRepository
  domain/      User, Order

6. Implementing Constants Management

ApproachWhen
Per-class constantsUsed only locally
final class ConstantsCross-cutting values
EnumClosed set with behavior
Properties fileExternally configurable

7. Implementing Exception Hierarchy

RuntimeException
└── AppException (base, has errorCode)
    ├── DomainException
    │   ├── ValidationException
    │   └── BusinessRuleException
    ├── NotFoundException
    └── IntegrationException
        ├── DownstreamUnavailableException
        └── DownstreamTimeoutException
  
RuleDetail
Unchecked by defaultEasier propagation
Carry contexterror code, correlation ID
No catch-and-swallowAlways wrap or rethrow

8. Implementing Utility Packages

PackageContents
utilGeneric helpers (avoid dumping ground)
supportFramework-specific helpers
commonShared types across features
Warning: A growing util package signals missing abstractions — promote to feature packages.

9. Implementing Code Documentation

AudienceDoc Type
Public API usersJavadoc with @param, @return, @throws
MaintainersWhy comments, not what
ArchitectsADRs (architecture decision records)
NewcomersREADME per module

10. Implementing File Organization

RuleDetail
One public class per fileJava requirement
File name = class nameRequired
Member orderstatic fields → instance fields → constructors → public → private
ImportsNo wildcard, grouped (java, javax, third-party, project)

11. Designing Namespace Structure

ConventionDetail
Reverse domainGlobally unique
No cyclesEnforce with build/ArchUnit
Stable depthAvoid 6+ nesting levels

12. Implementing Module Dependencies

RuleEnforcement
AcyclicBuild will fail or use ArchUnit
Inner depends on outer? NoDomain → no infra
Stable abstractionsStable modules expose interfaces
VersionedSemVer for shared modules