What is cohesion vs coupling trade-offs in practice?
Answer
Achieving high cohesion and low coupling simultaneously requires constant design trade-offs. The tension: communication between classes creates coupling, but putting all related code together increases cohesion — you can't eliminate all coupling. Types of coupling (from worst to best): (1) Content coupling — class modifies internals of another (worst); (2) Common coupling — share global state; (3) Control coupling — passing control flags; (4) Stamp coupling — passing complex data structures; (5) Data coupling — passing only necessary data (best); (6) Message coupling — passing messages via interfaces (ideal). Measuring cohesion — types (worst to best): Coincidental (random, unrelated); Logical (related by category but not functionally); Temporal (things done at same time); Procedural (follow execution order); Communicational (operate on same data); Sequential (output of one is input of next); Functional (everything contributes to single, well-defined task — best). Practical trade-offs: // Option A: High cohesion, higher coupling: class OrderService { private final OrderRepository orderRepo; private final PaymentService paymentService; private final EmailService emailService; private final InventoryService inventoryService; // All order operations here -- cohesive but tightly coupled to 4 dependencies } // Option B: Lower cohesion, lower coupling (too many classes): // OrderValidator, OrderPlacer, OrderConfirmer, OrderNotifier // Each tiny, loosely coupled, but hard to understand the flow. Sweet spot: classes that are functionally cohesive (do one clear thing) and coupled only through stable abstractions (interfaces, events). Too much decoupling → over-engineering. Too much coupling → unmaintainable spaghetti. Use coupling metrics in SonarQube or similar tools to guide refactoring.