Building Evolutionary Architectures: Support Constant Change
Rate it:
Read between July 10, 2021 - September 10, 2023
7%
Flag icon
A good example of Conway’s Law in action might be trying to change the contract between two services, which could be difficult if the successful change of a service owned by one team requires the coordinated and agreed-upon effort of another.
10%
Flag icon
For example, in the case of architectural fitness functions, issues like performance might conflict with security due to the cost of encryption. This is a classic example of the bane of architects everywhere — the tradeoff.
10%
Flag icon
Systemwide fitness functions allow architects to think about divergent concerns using the same unifying mechanism of fitness functions, capturing and preserving the important architectural characteristics.
16%
Flag icon
Here is an example of a fitness function defined at the technical architecture dimension to control the directionality of coupling between components.
16%
Flag icon
In the Java ecosystem, JDepend is a metrics tool that analyzes the coupling characteristics of packages. Because JDepend is written in Java, it has an API that developers can leverage to build their own analysis via unit tests.
42%
Flag icon
Later, she realizes dateofbirth isn’t needed after all. She could just remove the 24th migration, and the end result on the table is no column. However, any code written between the time Danielle ran the migration and now assumes the presence of the dateofbirth column, and will no longer work if for some reason the project needs to back up to an intermediate point (e.g., to fix a bug). Instead, to remove the no-longer needed column, she runs a new migration that removes the column.
50%
Flag icon
When architects think of migrating architecture, they typically think of the coupling characteristics of classes and components, but ignore many other dimensions affected by evolution, such as data.
50%
Flag icon
Transactional coupling is as real as coupling between classes, and just as insidious to eliminate when restructuring architecture.
50%
Flag icon
Architects aren’t immune to the “meta-work is more interesting than work” syndrome, which manifests in choosing inappropriate but buzz-worthy architectural styles like microservices.
50%
Flag icon
When decomposing a monolithic architecture, finding the correct service granularity is key.
50%
Flag icon
Creating large services alleviates problems like transactional contexts and orchestration, but does little to break the monolith into smaller pieces.
51%
Flag icon
Too-fine-grained components lead to too much orchestration, communication overhead, and interde...
This highlight has been truncated due to consecutive passage length restrictions.
51%
Flag icon
Sharing is a form of coupling, which is highly discouraged in architectures like microservices. An alternative to sharing a library is replication, as illustrated
57%
Flag icon
Because the framework calls the developer’s code, it creates a high degree of coupling to the framework.
57%
Flag icon
Contrast that with library code, which is generally more utilitarian code (like XML parsers, network libraries, etc.) and has a lower degree of coupling.
59%
Flag icon
In this case, PenultimateWidgets’ change wasn’t difficult from a data evolution standpoint because the developers were able to make an additive change, meaning they can add to the database schema rather than change it.
59%
Flag icon
What about the case where the database must change as well because of a new feature?
60%
Flag icon
To escape this antipattern, treat all software as just another integration point, even if it initially has broad responsibilities. By assuming integration at the outset, developers can more easily
60%
Flag icon
replace behavior that isn’t useful with other integration points, dethroning the king.
60%
Flag icon
Because they require huge investments of both time and money, companies are reluctant to admit when they don’t work.
62%
Flag icon
Microservices eschew code reuse, adopting the philosophy of prefer duplication to coupling: reuse implies coupling, and microservices architectures are extremely decoupled.
67%
Flag icon
Reporting is a good example of inadvertent coupling in monolithic architectures. Architects and DBAs want to use the same database schema for both system of record and reporting, but encounter problems because a design to support both is optimized for neither.
67%
Flag icon
Many microservices architectures solve the reporting problem by separating behavior, where the isolation of services benefits separation but not consolidation.
67%
Flag icon
Architects commonly build these architectures using event streaming or message queues to populate domain “system of record” databases, each embedded within the architectural quantum of the service, using eventual consistency rather than transactional behavior.
67%
Flag icon
A set of reporting services also listens to the event stream, populating a denormalized reporting dat...
This highlight has been truncated due to consecutive passage length restrictions.
76%
Flag icon
As developers learn to utilize these tools to support software development, we envision fitness functions based on AI that look for anomalous behavior.
76%
Flag icon
Traditional unit tests include assertions of correct outcomes within each test case.
78%
Flag icon
Alternatively, evolving implies fundamental change. Building an evolvable architecture entails changing the architecture in situ, protected from breakages via fitness functions.