Decoupling Between Functional Units (Components) Is A Must If:
- The functional units are already independent or loosely coupled in the target domain (from the conceptual perspective).
- The functional requirements allow asynchronous communication between the components. Even better: they are already modeled as asynchronous processes.
- The service component, which offers the services, is likely to change, what would break the "client" component.
- 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.
- Both components have different release cycles. Service component is likely to change, but the client component cannot be re-installed or rolled-out.
- Both components are going to be developed by different teams, or even some parts outsourced to other companies.
- An average RFE will cause only local changes in a single component and the decoupling / indirection will help you to isolate those changes.
- There are already different algorithms available for a given functionality or use case (see e.g. the Strategy Pattern).
- You are building an API or platform, which is going to be used by other applications.
- 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]
I am not sure I completely agree with every points, but I certainly agree with the basic statement: Applying the "loose coupling" hammer every time you see a nail is a bad idea.
We already learned that polluting your code with design pattern is not such a good idea. It's about time we start treating the more abstract principles (coupling, cohesion, etc.) the same way.
Posted by Itay Maman on August 27, 2009 at 05:08 PM CEST #
@Itay,
thanks - exactly. With which point you do not agree?
adam
Posted by 80.153.75.159 on August 27, 2009 at 05:26 PM CEST #
These are good rules to follow, but aren't these already established (and often forgotten) principles of Component based Development?
Posted by dvvrt on August 28, 2009 at 01:42 AM CEST #
@Dvvrt,
Yes - with CBD includes some of this ideas. However, CBD itself leads to another problem - procedural (aka serviceoriented) programming model :-).
thanks for your post!,
adam
Posted by Adam Bien on August 28, 2009 at 11:51 AM CEST #
Adam,
I am not sure I disagree, but I do have doubts about:
Point #1: Sometimes different concepts in the target domain can be realized by the same entity in the implementation space
Point #8: Many times I can see more than one algorithm that can solve the problem at hand. Yet, I would not recommend introducing a strategy pattern to accommodate every time that happens. Seems like a YAGNI to me.
Posted by Itay Maman on August 28, 2009 at 01:39 PM CEST #
Right:
Point #1: I meant e.g.: Address and Order can be placed in different namespaces, independent components, deployment units, because they are independent of each other in the target domain as well.
Point #8: If the algorithm is unlikely to change - than decoupling and even an interface are superfluous. See also: http://www.adam-bien.com/roller/abien/entry/a_good_architecture_is_all
thanks!,
adam
Posted by Adam Bien on August 28, 2009 at 02:09 PM CEST #