# Software Arquitecture
## Important Concepts
### Domain-Driven Design (DDD)
The concept of Domain-Driven Design implies that the structure of a software solution is built around a certain business domain and matches its requirements.
Core principles:
- **Context**:
- **Model**:
- **Ubiquitous Language**:
- **Bounded Context**:
#### Domain (domain layer or domain logic)
`A sphere of knowledge or activity`. Domain in the realm of software engineering commonly refers to the subject area on which the application is intended to apply
### Onion Arquitecture (hexagonal or clean)
The idea of the Onion Architecture is based on the inversion of control principle, i.e. placing the domain and services layers at the center of your application, externalizing the infrastructure.

### Command-Query Request System (CQRS)
CQRS is a development principle claiming that a method must be either a command that performs an action or a request that returns data.
Every action in Web API is either a request (get data) or a command (put data), but it shouldn’t do both. Consequently, each API method is divided into requests and commands.
It is like a puzzle
### EBI Arquitecture
### Ports and Adapter Arquitecture
Has three fundamental blocks:
- User interface
- business logic or application core (used by user interface to make things happend)
- infraestructure code (connects app core to tools: database, searh engine, 3rd party apis, etc).
Tipical application flow:
1. code in the user interface
2. to the application core
3. to the infraestructure code
4. back to application core
5. finally deliver a response to user interface
### Tools
- database engine
- search engine
- web server (driving)
- cli console (driving)
Connection
- **Primary or Driving Adapters**. `tell` our application do something.
- **Secondary or Driven Adapters**. `told` by our application to do something.
### Ports
A specification of how the tool can use the application core.
### Primary Adapters
Wrap around a Port and use it to tell the Application Core what to do.
Are Controllers or Console commands, and a port can be a service interface.

### Secondary Adapters
Implement a Port, an interface, and are then injected into the Application Core, wherever the port is required.
For example we create a persistent interface to connect to MySQL

### Inversion of control
A characteristic to note about this pattern is that the adapters depend on a specific tool and a specific port.
### Application core organisation
The Onion Architecture picks up the DDD layers and incorporates them into the Ports & Adapters Architecture.
#### Application Layer
Application services and/or Command handlers, typically their role are:
- use a repository to find one or several entities
- tell those entities to do some domain logic;
- and use the repository to persist the entities again, effectively saving the data changes.
#### Domain Layer
The objects in this layer contain the data and the logic to manipulate that data, that is specific to the Domain itself and it’s independent of the business processes that trigger that logic, they are independent and completely unaware of the Application Layer.
##### Domain Service
Sometimes we encounter some domain logic that involves different entities, of the same type or not, and we feel that that domain logic does not belong in the entities themselves.
The solution is to create a Domain Service, which has the role of receiving a set of entities and performing some business logic on them.
##### Domain Model
In the very centre, depending on nothing outside it, is the Domain Model, which contains the business objects that represent something in the domain.
### Components
Examples of components can be Billing, User, Review or Account.
#### Decoupling the components
Having completely decoupled components means that a component has no direct knowledge of any another component.
##### Triggering logic in other components
When one of our components (component B) needs to do something whenever something else happens in another component (component A).
We can make A use an event dispatcher to dispatch an application event that will be delivered to any component listening to it, including B, and the event listener in B will trigger the desired action.
- when the events can only be delivered asynchronously
- for contexts where triggering logic in other components needs to be done immediately, Component A will need to make a direct HTTP call to component B.
##### Getting data from other components
A component is not allowed to change data that it does not “own”, but it is fine for it to query and use any data.
###### Data storage shared between components
But it must use the data that it does not “own” as read-only, by the means of queries.
###### Data storage segregated per component
We have components with their own data storage means each data storage contains.
- A set of data that it owns and is the only one allowed to change
- A set of data that is a copy of other components data, which it can not change on its own, but is needed for the component functionality, and it needs to be updated whenever it changes in the owner component.
### Flow Control
The flow of control goes, of course, from the user into the Application Core, over to the infrastructure tools, back to the Application Core and finally back to the user.
#### Without a Command/Query Bus
The Controllers will depend either on an Application Service or on a Query object.
#### Example