Skip to content

Boundaries

Vanskarner edited this page Jul 26, 2023 · 7 revisions

CrossingBoundaries

All good architecture establishes boundaries between its parts, preventing them from knowing of each other's existence, which allows decisions to be postponed, saves time and avoids problems.

From the example diagram, boundaries are drawn to differentiate the purpose of each delimited area, thus distinguishing the following:

  • Both the User Interface Layer (Presentation) ⬇️ and the Persistence Layer ⬆️ point to the Business Logic Layer.
  • For the exchange of information, data structures cross boundaries. These data structures must not contain dependencies that violate the dependency rule.
  • Instead of the User Interface Layer calling the use case directly, it is proposed to do it through an abstraction (Services Abstraction), which follows a service-based execution approach.
  • The Business Logic Layer does not need to know the implementation details of the other layers, it only exposes a well-defined interface with the services it needs, as is the case of the repository (Repository Abstraction).

Therefore, from the above diagram, it can be specified how to cross these boundaries:

How to cross the boundaries

One of the keys to achieve a proper boundary crossing is to manage source code dependencies, so we can distinguish 2 ways:

Way 1: Flow of control crosses the boundary Way 2: Crossing the boundary against the flow of control
BorderCrossing1 CrossingBoundary2
It is a simple crossover from a lower level to a higher level. In the example, Customer requests to use the Service interface method and to use it it needs to know about Data as well. Here the boundary is crossed against the control flow where a higher level needs to invoke a lower level service. In the example, the higher level declares what it needs, and the lower level implements it.

The issue here is not that one way is better than the other, but rather where each is more appropriate to use. For example, the first way can be applied when the Presenter uses the use case services, while the second way is more appropriate for the use cases and the database.

Control Flow

Control flow refers to the sequence of instructions that are executed in a system, determining the order and manner in which operations are performed.

If we execute only the code of the diagram called form 2, the order of execution occurs from the upper level to the lower level ➡️, while the crossover or dependency occurs in the opposite direction ⬅️, so it is said that we cross the boundary against the control flow. Also, this control flow does not take interfaces into account because, at runtime, they do not exist.

Threads

Threading refers to the use of threads that allow tasks to be performed in parallel, which improves the performance and responsiveness of the application. It is perfectly valid for the use of threads to be present either in a single component or distributed in several components, since it does not represent architectural limits.

For example, built-in support for concurrency and thread management is provided in Java through the Thread class and other related classes, such as Executor, ThreadPoolExecutor, Future, CompletableFuture, etc.

For example, Java provides built-in support for concurrency and thread management through the Thread class and other related classes, such as Executor, ThreadPoolExecutor, Future, CompletableFuture, etc.

Clone this wiki locally