Need -> grepai search -> Found? -> extend/adapt | Not found? -> library? -> use | Create new
Checklist
Searched codebase for similar functionality
Checked for utility/helper
Found patterns to follow
Identified base classes
Evaluated library options
Good vs Bad Patterns
Area
Bad
Good
Naming
DataManager, Helper
OrderRepository, PriceCalculator
Reuse
Create new utility
Extend existing, use library
State
Mutable shared state
Immutable, stateless
Coupling
Direct deps everywhere
Interfaces, DI
Modules
Mega-module
Cohesive single-purpose
Inheritance
Deep hierarchy (>3)
Composition, delegation
Functions
Side effects + logic
Pure functions, separate I/O
Config
Hardcoded values
Externalized
Errors
Swallow exceptions
Fail fast, explicit types
API
Leaky abstractions
Stable contracts, versioning
Module Decomposition
Principle
Description
Single Responsibility
One reason to change
High Cohesion
Related functionality together
Low Coupling
Minimal inter-module deps
Information Hiding
Impl details private
Stable Abstractions
Depend on abstractions
Boundaries
Signal
Action
Shared vocabulary
Same module
Independent deployment
Separate
Different change rates
Separate
Team ownership
Align with team
Shared data model
Same bounded context
Decomposition
Strategy
When
Example
Domain
Business capabilities
orders, payments, users
Layer
Technical concerns
api, domain, infra
Feature
Vertical slices
user-registration, checkout
Actor
User types
admin, customer, merchant
Data Access
Layer
Responsibility
Depends On
Controller
HTTP, validation
Service
Service
Business logic
Repository
Repository
Data abstraction
Domain entities
DAO (opt)
Low-level DB ops
Database
Rules
Do
Don’t
Controller -> Service
Controller -> Repository
Logic in Service
Logic in Controller
Return domain objects
Return DB entities
Interfaces between layers
Tight coupling
Transactions in Service
Transactions in Controller
Flow: Controller -> Service -> Repository -> DB (validation -> logic -> mapping)
Utility Classes
When to Create
Create
Avoid
Stateless ops
Stateful utilities
Pure functions
Side effects
Cross-cutting
Domain-specific
No existing library
Reinventing wheel
3+ usages
Premature abstraction
Naming
Suffix
Purpose
Example
*Utils
Static, stateless
StringUtils
*Helper
Instance + deps
FormHelper
*Support
Framework integration
TransactionSupport
*Factory
Object creation
ConnectionFactory
*Builder
Fluent construction
QueryBuilder
*Converter
Type transformation
DtoConverter
*Validator
Validation
InputValidator
Composition over Inheritance
Prefer
Over
Why
Has-a (composition)
Is-a (inheritance)
Flexibility
Interface impl
Class extension
Multiple behaviors
Delegation
Overriding methods
Clear responsibility
Strategy pattern
Template method
Runtime flexibility
Delegation Example
class OrderService { private final PriceCalculator calculator; private final OrderValidator validator; private final OrderRepository repository; public Order process(OrderRequest req) { validator.validate(req); return repository.save(new Order(req, calculator.calculate(req))); }}