The architecture of a software system is the shape given to that system by those who build it.
The purpose of that shape is to facilitate the development, deployment, operation, and maintenance of the software system contained within it. […] the architecture of a system has very little bearing on whether that system works.
The way you keep software soft is to leave as many options open as possible, for as long as possible.
All software systems can be decomposed into policy and details:
The goal of the architect is to create a shape for the system that recognizes policy as the most essential element of the system while making the details irrelevant to that policy. This allows for decisions about details to be delayed and deferred to the last possible moment when the amount of information is highest.
A good architecture must support:
There may be times when things look similar, maybe even identical, but their futures aren’t. Such pairs shouldn’t be considered duplicates and unified, because separating them later is much tougher. This happens often when separating Use Cases into their vertical slices, and coupling them because their DB queries or algorithms are similar.
Use Cases and Layers can be decoupled in many ways: at source code level, at binary code (deployment) level or at execution unit (service) level.
[…] it’s hard to know which mode is best during the early phases of a project. Indeed, as the project matures, the optimal mode may change.