Tactical Domain-Driven Design with Angular and NX in details: Code organization, Monorepo interaction, Entities Behavior

Code organization on a tactical level
The following five categories of layers or libraries are distinguished according to the Nrwl.io’s Enterprise MonoRepository Patterns:
  • Feature category that has components for various use cases, for example, search-flight component.
  • UI category has dumb components. They are case-agnostic and therefore usable—for example, date-time component, address component, or address pipe.
  • API category that exports building blocks from the current subdomain for other subdomains. The best example is Flight API.
  • Domain category comprises the following domain models used by the domain column: classes, interfaces, types, etc.
  • Util category that contains general utility functions, formatDate, for example.
The confusion in the complete architectural matrix can lead to tragic consequences. The code organization is essential. Without it, you can face considerable difficulties when code reuse and features are simply impossible. Isolate the Domain It is clear that domain has to be isolated to get the correct processing of the domain logic. In Angular, we use facades to hide it behind. Each one of the dedicated to representing the specific manner of domain logic's usage: In DDD, facades are called application services and get along well with facades in Angular. The essential point is to segregate infrastructure requirements from the actual domain logic on an architectural level. Data exchanges, asynchronous communication with the server are usual infrastructure issues in a single-page application. The result of maintaining this separation is the appearance of three additional layers: facades/application services, actual domain, and infrastructure. You may pack them in their own libraries or store them in a single subdivided library. The second way is preferable if these pack layers usually use together.
Implementations in a Monorepos
Now that we clarified architectural components issues, we should realize how to implement them in Angular. To achieve this goal, Google usually recommends monorepos. Monorepos, as we remember, is one repository for all libraries. Angular CLI is a monorepo itself, but Nx offers additional features that can be pretty valuable for large enterprises. For example, the ways to introduce access restrictions between libraries to prevent a highly coupled overall system. As you remember, a weak connection increases maintainability, so for large software systems, this feature is valuable. Monorepo requires one instruction only to create a library : Instead of ng generate module, you are using ng create library, and that's it. As a benefit, you are getting weaker coupling in a cleaner structure with improved maintainability. Nx allows grouping libraries by domain using switch directory, which determines an optional subdirectory.The incremental builds enable by the second switch - buildable. The names of the libraries included in the layer would be reasonable to use as the prefix, naming layers like feature-search or feature-edit. The domain library in this example is divided into three further layers. It allows isolating the exact domain model:
Builds within a Monorepo
Nx uses the git commit log to determine which libraries are affected by the recent code changes. Thus, only the affected libraries recompile or simply run their affected tests, which saves time on large systems that are entirely stored in a repo.
Entities and your Tactical Design
By Tactical design, you may implement various ideas to structurize the domain layer. For example, there are an enum and two entities in the center of this layer, which corresponds to the usual representation in object-oriented languages. To guarantee the immutability of the state of these entities, their information is hiding, as it's usually practiced in OOP. We can implement it using private fields and public methods to operate on them. The setStatus method indicates the encapsulation data and business rules in these entities. It should be remembered that DDD set domain services if we can't meaningfully accommodate business rules in an entity. The entities that only represent data structures are frown for the DDD. They are the so-called anemic model. You can be charmed that it looks like a real one, and indeed: the objects are connected with structure in a rich relationship, like it has to be in accurate domain models. But take a closer look; these objects show almost no behavior, making them nothing more than bunches of useless code.