Business Automation using Microsoft Power Platforms
Fintech
Binding seamless Technology with Finance
General Published on: Fri Feb 10 2023
It’s rare to see a project achieve its ultimate form, if one even exists, following a single cycle of planning and execution in modern software development. Market demands evolve, assumptions are tested, and perceptions shift. Discovery begins before the first line of code is written and continues throughout the project’s life cycle.
However, only feedback can lead to a change in perception. This could be due to end-user-driven changes in requirements, a product owner’s a more complex design, or a developer discovering that code they tried to implement is logically inconsistent. Discovery is thus a collaborative process that anyone who has used an agile development methodology will be familiar with.
A mental model that gathers the business rules and relationships to be expressed in code and rectified by a continual refactoring process is a result of this ever-evolving understanding.
Domain-Driven Design is a software development approach that focuses on the model of the business problem being solved and allows both technical and non-technical people to participate in its discovery through the use of a common language known as the “Ubiquitous Language.” Once a model has been established in this language, it may be converted into readable code using a common set of building blocks. Because the model can develop in response to product iteration, this methodology lends itself particularly well to Agile Development methodologies.
The following sections will walk you through the steps of discovering a model and implementing a solution in code. Wherever possible, alternative methodologies will be used to explain the motivations for Domain-Driven Design.
We should aim for loose coupling and strong cohesiveness in the codebase when developing new software and refactoring legacy code; software components should have little direct knowledge of the inner workings of other components, and each module should have a clear and single purpose.
Domain-Driven Design results in a layer of software that is already detached from the rest of the system. Because business rules are separate from the user interface, persistence details, and third-party services, they can be simply (and quickly) tested.
Most modern web frameworks for PHP are based around the Model-View-Controller pattern. Each layer’s function could be summarised as follows:
Each of these layers is reliant on the others in some way, and each serves multiple purposes. Each action that is performed by the application is bound to the controller coordinating it and the model is in charge of both business logic and persistence.
By creating a dependency rule, we can decouple these layers:
Enter Hexagonal Architecture is also known as the Ports and Adapters.
The outer layers may only depend on inner layers. The inner layers should not be reliant on the outer layers. Each layer is defined as follows.
The Infrastructure Layer contains code that interfaces with application infrastructure – controllers, UI, persistence, and gateways to external systems. Many of the objects found in this layer will be provided by a web framework or persistence library. Concretions of domain repositories are placed in this layer while the actual interfaces are defined in the domain layer.
The Application Layer provides an API for all functionality provided by the application. It accepts commands from the client (whether web, API, or CLI) and translates these into values understood by the domain layer. As an example, a RegisterUser service would accept a Data Transfer Object containing a new user’s credentials and delegate responsibility for the creation of a user to the domain layer.
The Domain Layer contains any core domain logic. It deals entirely with domain concepts and possesses no knowledge of the outer layers.
We’ve talked about the domain model and the application services that surround and interact with it up to this point. These application services, on the other hand, are entirely useless if clients can’t use them, which is where ports and adapters come in.
A port is a special type of interface between a machine and the outside world that was created for a specific purpose or protocol. As a result, we can define the port as a technology-independent application programming interface (API) that was created for a specific form of interaction with the application (hence the word “protocol”). It’s entirely up to you how you define this protocol, which is part of what makes this method so appealing. Here are some examples of the various ports you might have:
Let’s have a look at the hexagonal architecture diagram again:
A port is represented on each side of the inner hexagonal. This is why this architecture is frequently shown in this way: you have six sides out of the box, each of which can be used for a different port, and plenty of room to plug in as many adapters as you need.
As I already stated, ports are technology agnostic. Even so, you use technology to communicate with the system: a web browser, a mobile device, a dedicated hardware device, a desktop client, and so on. Adapters are very in this situation. An adapter enables interaction through a specific port and with a certain technology. Consider the following scenario:
Numerous adapters for a single port are possible, as well as a single adapter for multiple ports. You can add as many adapters as you want or need to the system without affecting the other adapters, ports, or domain model.
Hopefully, this gives you an idea of why I’ve enjoyed working with Domain-Driven Design and hexagonal architecture. No approach is perfect, but I’ve always found it important to plan to make software that can be maintained for decades to come.
Get 30 Mins Free
Personalized Consultancy