|
"High cohesion, low coupling" is one of the most misunderstood principles in software engineering. So, let's clear things up! TL;DRCohesion is about the internal focus of a thing - how well its components work together to fulfil a single purpose. Coupling is about the external relationships between things - how much they depend on one another. CohesionWhen applied to a code module, cohesion measures how closely related its functions are. An Authenticator module will likely have high cohesion because all its functions are related to handling authentication. On the other hand, a Utils module is likely a dumping ground for unrelated helper functions and will, therefore, have low cohesion. When applied to a system, cohesion measures how well its components (services, subsystems, etc.) work together to achieve a single goal. A service with well-defined boundaries and responsibilities will have high cohesion. Conversely, a system has low cohesion if its components are poorly aligned and have overlapping or unrelated responsibilities. For example, a User service that handles authentication, account management and sending notifications about account updates. CouplingA good way to think about coupling is in terms of change propagation. That is, how much does System B need to change if we change System A. Coupling is everywhere and comes in many different forms. Some coupling (e.g. data format dependency) requires coordinated changes between systems. Other forms of couplings are less obvious but more problematic to deal with. For example, temporal coupling links the availability of one service to another. This often leads to cascade failures and necessitates other practices (e.g. retries, exponential backoff, fallbacks, chaos engineering and so on) to mitigate. ----- So there you have it, the difference between "Cohesion" and "Coupling". They measure similar but, ultimately, different qualities in software. |
Join 17K readers and level up you AWS game with just 5 mins a week.
Lambda Durable Functions makes it easy to implement business workflows using plain Lambda functions. Besides the intended use cases, they also let us implement ETL jobs without needing recursions or Step Functions. Many long-running ETL jobs have a time-consuming, sequential steps that cannot be easily parallelised. For example: Fetching data from shared databases/APIs with throughput limits. When data needs to be processed sequentially. Historically, Lambda was not a good fit for these...
Step Functions is often used to poll long-running processes, e.g. when starting a new data migration task with Amazon Database Migration. There's usually a Wait -> Poll -> Choice loop that runs until the task is complete (or failed), like the one below. Polling is inefficient and can add unnecessary cost as standard workflows are charged based on the number of state transitions. There is an event-driven alternative to this approach. Here's the high level approach: To start the data migration,...
Lambda Durable Functions comes with a handy testing SDK. It makes it easy to test durable executions both locally as well as remotely in the cloud. I find the local test runner particular useful for dealing with wait states because I can simply configure the runner to skip time! However, this does not work for callback operations such as waitForCallback. Unfortunately, the official docs didn't include any examples on how to handle this. So here's my workaround. The handler code Imagine you're...