Introduction
As a forewarning, this is not a complete description of the actual architecture of Eye Closely. It is but a set of architectural guidelines. It is based on the need to minimize time to production, time and cost to deploy changes, and minimize the likelihood of bug occurrence.
As a consequence the guidelines are the closest to what is described as Vertical Slice Architecture by Jimmy Bogard. It may not be the best choice solution for every problem. It may not work well for inexperienced teams who may mistake it for an opportunity to write "spaghetti code". It is a tradeoff. Just as any other archtectural choice.
As such, in the following description, all principles should be seen in light of the limited scope described herein. The scope does not have tens of thousands of users, and has a very limited number of engineers as a consequence.
Summary - what are the main principles for Eye Closely architectural style?
- Polite tests that don't mock anybody, unless the alternative is an arrogant test running for longer than ~200ms
- Domain and language matters, but it should not exist merely in a vacuum of abstract space
- Code that changes together, lives together to minimize the wayward travels of an errant software engineer in code
- Both vertical slices and horizontal layers must be short and narrow
- A computer is an employee and should be granted some time for rest and recuperation
Polite tests, no mocking
Tests are good. Tests make software work better. Mocking makes testing easier, but especially in weakly typed languages, it is often the place where the abstraction leaks and the code will break into multiple pieces.
Therefore in Eye Closely the tests execute the codepaths in full whenever possible, and as a consequence there is a lot of testing against the real database. This means that the database setup itself must be light-weight when the tests are executed. Enter the powers of empty test databases. All vertical slices that require database to be present, implement only the database changes that they require to work, and always do so in full.
This includes database changes, and database users required for the vertical slice. This way the changes and the database model can be tested independently, without any additional dependencies. It is fast, as there are quite a few changes per vertical slice.
Of course every test still adds its tiny expenditure of time, but the ability to test the vertical slices independently in full, including E2E tests, makes the local development remain as fast as it ever was.
Exceptions always exist, in particular with external services coming into play.
Domain matters, but not in a vacuum of abstractions
As part of DDD (Domain Driven Design), the domain should be placed in the center of everything. And that is a good thing. Solving a problem inside a domain is what provides the value.
However, having a domain layer in a layered architecture does not inherently solve any problems. The users still need an interface, the application still needs to validate the data, the database still needs to persist. Most actions that users desire to take, and the results they expect, require all the above to solve a problem.
It does not mean the code requires no separation of concerns, but there is no need to have decoupled layers through dependency inversion. More on it in later posts.
Code that changes together, lives together
This one is the most important rule. Coming straight from the Vertical Slice Architecture principles. It promises that the changes to application features are simple. It doesn't mean that there can "never" be any layers or no decoupling, if required. It means those principles are applied only if necessary for providing better test coverage or when having multiple similar systems that need to have a similar interface.
It also means that a single page implementation that solves a problem in a given domain may often live in a single file. It is not as clean, but it is efficient. It is easy to debug. It is easy to understand and modify even if the original intention has been lost in time.
Vertical slices and horizontal layers must be short and narrow
What is a vertical slice? At minimum a single page. At most a bounded context as in DDD. It should have a singular purpose. Solve a single problem for the user and not go any further. It cannot depend on any other vertical slice.
What is a horizontal layer? A module available for vertical slices to use.
Why don't vertical slices contain layers? Layer separation is one of the ways to maintain code, but having many different layers that are all aware of the domain, is not. What if the entire internet was built on domain aware model instead of TCP/IP? It would require a mighty fine governmental level orchestration to make use of it.
This means that where layers get used, they are built as agnostic to the domain. It means that layers are thin "horizontals" rather than domain specific independent layers in all verticals. Sometimes the latter cannot be avoided, but it is not the goal of this architectural strategy to provide a uniform decoupling between layers that directly serve the interests of the same domain and require the knowledge of the domain.
This in turn means that most of the time it is unnecessary to provide a separate repository layer. It may not be a good idea in an enteprise environment where a service might be replaced with something else quite frequently and business rules rarely change. It is fine for Eye Closely, because the primary database technology will never be replaced.
Computer is an employee
New code is "hired" to perform the jobs that need to be done, instead of hiring a new person to do the job. Up until to the point where it is no longer possible. Up til then automation rules supreme.
Why? Because a computer eats less, doesn't complain as much,(never mind, it does) and keeps doing their job 24/7. Still, computers should be granted sleep time as well, and that is what Eye Closely systems are doing until something is requested of them. Also, people have better things to do than basic data manipulation and their lives to live.
Summary
Thank you for reading the architectural guidelines of Eye Closely. In the following posts, each of the items will be covered in more detail.