Page History
Frequent Scenarios
There are certain scenarios that you will frequently encounter on a project. We want to highlight 4 of those scenarios in the context of the clean architecture. They are shown on the schematic to the right.
Application to Domain (1)
You will always have this transition when creating an application with some sort of flow in it that displays pages to the end user. As in the example above, the flow determines how a use case of the application works, and uses the domain layer. If you have a Blueriq as a Service (BaaS), then this might skip the applications layer.
Persistence of data (2)
Data needs to be read from or written to a database. This usually happens at the start or the end of the flow, respectively. The service in the interface layer reads and writes to the database. The translation to the internal format is done by the applications layer, and in studio can be seen in the data-mapping. The mapping translates information from the domain layer into a format that is suitable for the database and stores it; and vice versa.
Calling a web service (3)
There often is a need to communicate with an external system or party. This communication is frequently handled with REST or SOAP services. As there is a contract for a web service, you need to adhere to it. the information located in the domain layer needs to be translated into a format that fits this contract.
Showing data to customer facing applications (4)
The flow in the application layer describes the use case, but the user interface is responsible for showing the information to the end user. So, actions from the end user (pushing a button) trigger behavior in the use case. The use case is unaware of what kind of user interface is used (MVC, XSLT, command line...)
The
Theneed for decoupling
The clean architecture works well for any programming language. Once the domain layer is defined, the application layer can build on that. The internals of the domain layer are placed in methods, and the methods can be used in the application layer. A method in above example could be registerNewRenter(Person person)
of the House
class. What exactly is happening inside that method is hidden from the application layer. Only when the footprint of the method changes does this have impact on all classes in the application layer that use the method. Luckily do footprints of methods change much less frequently than the internals of the method.
In Blueriq is everything included in an interaction module. This means that your flow has access to each and every element in the domain of the domain layer. This is in principle correct, and adheres to the dependency rule of the clean architecture. What this however implies, is that changing any element of the domain layer may have an impact on the application or interface layer. This was not your intention however, as you also expose internals to the higher layer. In any object oriented programming language, you expose a method or interface to another class, but not the inner working of the method. In Blueriq there are no methods, meaning that all internals are exposed, and can be seen as method or interface. Even though this adheres to the dependency rule, this is much more than intended or needed. As a result, before changing any small thing an impact analysis needs to be performed. This can be achieved by using the dependencies in studio. Having to do this for every element is however a tedious job, and mistakes are bound to happen. This leads to:
- Additional work to check for the impact of every change
- People being scared to make changes
- A preference for creating new attributes above reusing/refactoring old ones, cluttering the domain
- An overflow of elements in studio, which reduces the working speed and increased the mental load
Include Page | ||||
---|---|---|---|---|
|
It would be great however if you can know for sure what elements can be changed without any impact on the higher layers, and which ones should be changed with care after an impact analysis. What we essentially want to achieve is that only a small set of elements has this dependency (you can also say that it is coupled), and you can quickly and easily change all other elements. This small set of elements can be regarded as the method footprint if you think of it as code. This leads to
- Quicker development
- Better test-ability
- Confident business engineers
Thinking of the original layered structure, you might add an additional layer to visualize this idea in Blueriq, which might not be needed in programming languages. On the right side, we call this new layer Commons. In this layer you place anything that should be shared between the interfaces and applications layer and the domain layer. This could include
- Attributes that are used as function parameters
- Web service contracts
- AQ_StartProject input
- ...
Although the dependency rule allows dependencies between interface/applications and domain, we now only allow dependencies between interfaces/applications and commons. This way, it is possible to change the internals of the domain layer without having impact on the outer layers.
You might also just regard the Commons layer as part of the Domain layer, as method names in code are also part of the domain layerThe core of Blueriq is its knowledge modelling capabilities. That is what most time is spent on, and delivers most value to our customers. This functionality is in the domain and application layer. We have to integrate to external systems, but that is all abstracted away in the model, with a simple service type. There are also no details on how the front-end is creating a running page, only an abstract definition of what should be placed on a page. So you envision the outer two layers, the interfaces and adapters layer as rather thin in the Blueriq model, as shown on the right.
When a layer boundary is crossed, then this is a good opportunity for decoupling. There actually might also be The adapters layer sole responsibility is to decouple the center of the onion with outer layer. As the center of the onion is so large in Blueriq, there actually is also a need for decoupling when staying in the same layer. For example, lets say a calculation for the maximum lease amount of a car is dependent on the risk score of a customer. Both of these numbers are part of the domain layer. You may however want to decouple each calculation so that all internals of a single calculation may be refactored and maintained easily, and are not 'in the way' when working at other parts of the application. So, to summarize, the application of decoupling can be split up into two categories:
- Decoupling to prevent layers blend into each other.
- Decoupling to expose functions within the same layer.
The next section of this guide describes concrete patterns of how this can be achieved: 4. DecouplingPatterns
Info |
---|
| ||
Sidenote: Creating custom codeWhen creating a project with Blueriq for a customer it is often not avoidable to create custom code. The minimum is the styling of the runtime for the specific customer, but you also can create custom containers and services and other components. Using the notion of layers in the clean architecture, we can nicely plot where the custom code should be, and where it should be located. In the Applications and Domain Layer no custom code should be found. These are all functions that Blueriq supports out-of-the-box. If the functionality in these layers us not sufficient, then a feature request should be created to enrich the software. Any custom code in these layers is undesired. In the Interface Layer the desired custom code is found. These are connections to external (legacy) systems or databases that are customer specific and that will never be supported in the product. |
Info | ||
---|---|---|
| ||
Typical example: A Blueriq Project StructureIn Blueriq it is possible to stack modules on each other to reuse elements from lower modules. This enables the use of generic functionality in lower modules, and specializing them in a specific module if changes are needed. These modules should represent business concepts, such as a product being sold. In below structure, the middle layer represents different labels of the company which are similar to each other in most aspects, and therefore use the same generic library. Each of these labels is represented to the end-user using a certain channel. Examples of such channels can be a website or an app on the phone or tablet. For each channel you want to change the behavior of the application slightly so that the user experience is changed to optimally function for that specific channel. This represents the top layer of the structure. The underlying idea why this structure is agile and maintainable is that you can perform changes on the level that fits the change. In case that Label C has a slight variation on the rules, then you would create that logic in the Label C module. In case you want to split up your pages for Channel 2 (as that might be a mobile channel), then you change your flow in the Channel 2 module. If a change should be applied to all applications, then you perform it in the generic base module. When making changes you should consider when functionality should be moved up or down the module structure. You should make functionality more generic (moving down) when similar functionality is implemented in horizontally aligned modules. You should make functionality more specific (moving up) when you notice that each upper module changes the functionality significantly. A common pitfall is to create functionality in the generic layer while it is not generic (yet). The advantage of this is that small changes could be implemented quickly. The disadvantage of this approach is an undesirable growth of the generic layer which leads to a high number of dependencies through the application landscape. Small changes usually are:
|