I found some notes I took in 2004 at a lecture I attended on coupling. It may have been a lecture Dave Thomas gave at CJUG.
Decoupling your code:
coupling: you can change something, and something else changes too
Methods calling methods: hard to understand, hard to maintain, hard to re-use.
Symptoms: Minor change recompiles the whole system. Unit tests require every jar on the box. Things stop working when you change their context. Hard to partition project between subteams.
Treat code like spy cells: limit interactions, if one is broken all others are safe, enforced structure.
Some coupling is good. Some code must call other code. Make it deliberate.
Types of coupling: Static, dynamic, domain, temporal.
Classes are staticly coupled if one needs another to compile.
Java has interfaces. Good to couple to something more abstract. Gang of Four says to program to interfaces.
Interfaces reduce coupling. Split intent from implementation, single point of abstraction. Interfaces != list of class’s methods.
Inheritance is also static coupling. What if parent class changes?
Different rules for inheritance. Java: easy to inherit, hard to delegate. Inheritance is okay for “is-a”, bad for “has-a” or “uses-a”. Business world – not many uses for “is-a”, more “has-a” and “uses-a”
How to delegate?
happens at run-time. method chaining: order.getCustomer().getAddress().getState()
coupling question: what can change? What can break? Those methods can change.
Start by asking what caller is doing. Express intent at point of call.
Large-scale coupling: Compiling is transitive: a -> b, b -> c, then a -> c
can be circular.
use observer pattern: can break circular chains. Linear chain: add a layer. Mediator class. Is that a GoF pattern?
Mediator: construction manager. You deal with manager, manager deals with subcontractors. manager negotiates between subcontractors.
Subsystems: Things that need to be coupled tend to cluster. make each a subsystem. Ex: java package. Put a facade on a package. Security: read facade, read-write facade, returned via factories.
Business rules in code. When rules change, code must change. Value can be parameterized. Behavior can be too. Use interpreter. Interpreter pattern. Define action codes (pick out verbs)
Add strings of action codes to database.
Action code: idea from cobol. Do a search. Book idea: Cobol Principles for Java
not GoF intprepter pattern. Give users a screen to link product and actions.
Coupling in time: dependence on sequence of events. imposing a sequence where none is needed.
Recommended: first edition of Bertrand Nayer’s book
Invariant: something that must be true. Invariant must be true at all times.
Design for concurrency. Do stuff in parallel. use a state machine. Can use mediator pattern. Threads: hard, okay with hash maps. Processed-based: RMI, SOAP. Message-based: JMS
Static coupling: reduce with interfaces, facade, delegation
Dynamic coupling: reduce with mediator, command pattern, express intent at point of call
Domain coupling: reduce with metadata, interpreter
Temporal coupling: reduce with monitor and maintain class invariants, synchronize correct places, parallelism
Image from Wikimedia, assumed allowed under Fair Use. Image from the Vatican Virgil, a 5th century manuscript of poems by Virgil.