Temporal Coupling in Code | Better Programming

We often talk about coupling, what exactly is coupling?

Chunting Wu
Photo by Florian Olivo on Unsplash

From the previous section, we learned that purchase should only need to process payments, the rest of the behavior is additional, and should not be in the same life cycle as purchase. In other words, even if the giveCoupon fails, it should not affect purchase or lottery.

In my previous article, we mentioned that whenever failures can happen, we have to expect them and handle them gracefully. This is called resilience engineering.

  • At least once
  • Exactly once

The story isn’t over yet. We can already ensure that emitted events are executed. What if the event isn’t sent at all? Continue to take purchase as an example, when payByCreditCard has been successful, but it doesn’t send the event due to the system crashes for unexpected reasons. Then, even with a message queue, we still get the incorrect result.

This time we are still going through a step-by-step evolution of the system as we did in Shift from Monolith to CQRS to let you know how to decouple when systems become large and complex. At the beginning, we first decoupled source code and execution timing through domain events; then we introduced message queues with message producers and consumers to achieve system-level decoupling.

  • Attempting to be as reliable as possible, so introduce message queues, which should be 99% sure that there will be no problems. But there is still 1%, is such a risk bearable?
  • Implementing event sourcing comes at the cost of increased complexity and performance may be affected. Is this acceptable?

Leave a Comment