What is it?
The degree to which things things must be changed together. There are a number of different types of coupling.
Implementation coupling
If two components display implementation coupling then, when the implementation of one changes, the implementation of the other must also change. A high degree of implementation coupling reduces stability and maintainability.
We can reduce implementation coupling by introducing well defined interfaces between components. Interfaces are far less volatile than their implementations and act as a contract between components. The implementation of an interface can change but as long as the interface itself doesn’t change then components that are dependent on that interface are unaffected.
This is the principal of information hiding and it can be applied at the code level (encapsulation) all the way up to the service level. The more terse and stable a service’s interface is the less chance changes to that service will impact and dependent services.
Temporal Coupling
At the class level, temporal coupling is usually exhibited when members of a class must be called in a particular order. This can often be overcome by using either constructor injection or the factory pattern to avoid the need to mutate an object’s state.
At the service level temporal coupling can be found when we make inter-service calls where the calling service is dependent on the response of the called service. High degrees of temporal coupling increases latency and decreases resilience and reliability. For the use case to be operational, all of the services in temporally coupled system have to be available.
Temporal coupling between services can be reduced by introducing asynchronous communication methods, usually a service bus, and caching. Both approaches reduce the need for services in a chain be available at a specific point in time.