Group Classes That Change Together
Classes that change for the same reasons and at the same times should be in the same component. This is the Common Closure Principle (CCP) - the Single Responsibility Principle for components.
Incorrect (classes that change together are separated):
src/
├── entities/
│ └── Invoice.ts # Changes when billing rules change
├── repositories/
│ └── InvoiceRepository.ts # Changes when billing rules change
├── services/
│ └── InvoiceService.ts # Changes when billing rules change
├── validators/
│ └── InvoiceValidator.ts # Changes when billing rules change
└── mappers/
└── InvoiceMapper.ts # Changes when billing rules change
# A billing rule change touches 5 directories
# Risk of forgetting one, inconsistent changes
Correct (classes that change together are grouped):
src/
├── billing/
│ ├── domain/
│ │ ├── Invoice.ts
│ │ ├── InvoiceLine.ts
│ │ ├── InvoiceRules.ts
│ │ └── InvoiceValidator.ts
│ ├── application/
│ │ ├── CreateInvoiceUseCase.ts
│ │ └── ports/
│ │ └── InvoiceRepository.ts
│ └── infrastructure/
│ ├── PostgresInvoiceRepository.ts
│ └── InvoiceMapper.ts
├── payments/
│ └── ... # Changes for different reasons
└── shipping/
└── ... # Changes for different reasons
# Billing rule change isolated to billing/
# Single PR, single review, single deployment
How to identify change reasons:
- “When X business rule changes, which classes change?”
- “When the Y team requests a feature, which code changes?”
- Group by actor/stakeholder, not by technical layer