adam bien's blog

Decoupling Between Functional Units (Components) Is A Must If: 📎

  1. The functional units are already independent or loosely coupled in the target domain (from the conceptual perspective). 
  2. The functional requirements allow asynchronous communication between the components. Even better: they are already modeled as asynchronous processes.
  3. The service component, which offers the services, is likely to change, what would break the "client" component.
  4. The service component is not technology or even vendor agnostic. Direct communication with such service component would "pollute" all clients. Encapsulation is a must in this case.
  5. Both components have different release cycles. Service component is likely to change, but the client component cannot be re-installed or rolled-out.
  6. Both components are going to be developed by different teams, or even some parts outsourced to other companies.
  7. An average RFE will cause only local changes in a single component and the decoupling / indirection will help you to isolate those changes.
  8. There are already different algorithms available for a given functionality or use case (see e.g. the Strategy Pattern).
  9. You are building an API or platform, which is going to be used by other applications.
  10. Obvious: the UI should be always decoupled from the business logic realization. Multiple UIs (e.g. JSF, RIA, IPhone) are very likely - also in enterprise environment.

Decoupling or modularization do cause additional coding / conceptual / auditing (e.g. metrics) effort. The reason / intention for decoupling or modularization has to be clearly documented, otherwise the resulting code can be hard to understand and, in long term, to maintain.

 [Data Transfer Objects are often introduced to increase decoupling, see page 153 in "Real World Java EE Patterns - Rethinking Best Practices" and Premature Encapsulation Is the Root of All Evil, Page 253]