Don't over-enforce architecture

Whichever architectural pattern you choose, the main priority of the application should be the business domain. This is true for both finding reasonable, domain-motivated modules, but also how to structure the packages within a module, so that developers can work with it with least effort.

This is one important thing to note: developers should be able to work on the project without too complex or overly enforced structures and architectures. We have seen too many examples in the past that deliberately used technically driven layers or overly strict patterns, just to match the book and fulfill certain constraints. But these constraints are often self-motivated and don't fulfill any higher purpose. We should sensibly reconsider what is required and what just bloats the development processes. Search for the term cargo cult programming when you have the time, and you will find an interesting real-world story of following rules and rituals without questioning their purpose.

Therefore, don't over-complicate or over-enforce architecture. If there is a simple and straightforward way that fulfills what currently is required, just go for it. This is not only true for premature refactoring, but also for architectural design. If putting a few classes in a single, well-named package serves the purpose and clearly documents the reasoning, why not? If a business use case boundary class can already fulfill the whole, simple logic, why introduce empty delegates?

The trade-off of following an architectural pattern, even if not required in all places, is consistency versus simplicity. Having all packages, modules, and projects showing the same patterns and structure shows a picture familiar to developers. However, in Chapter 8, Microservices and System Architecture we will see that in greater detail, ultimately, consistency is a goal that isn't likely to be achieved within the whole organization, or even single projects. The benefits of crafting something simpler and eventually more flexible outweighs uniformity in many cases.

The same is true for overly trying to encapsulate the implementation using technical layers. It is definitely the case that modules as well as classes should encapsulate implementation details and provide clean and clear interfaces. However, these responsibilities can and should be contained in single, ideally self-sufficient packages or classes. Packaging the module's concerns by technical terms ultimately exposes the details to the rest of the module, for example, that a database or a client to an external system is being used. Organizing by domain motivation first, enables us to encapsulate functionality into single points of responsibility, transparent to the rest of the modules or application.

In order to prevent accidental misuse of a way of packaging, the easiest and most transparent way is to introduce static code analysis. Package imports in classes and whole packages can be scanned and analyzed to detect and prevent unwanted dependencies. This represents a security measurement, similar to test cases, to avoid careless mistakes. Static code analyses will typically run as an extended part of the build process on the Continuous Integration server, as they may take some time to build. In Chapter 6, Application Development Workflows we will cover this topic in more depth.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.107.152