mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
add docs
This commit is contained in:
parent
2053cd7f05
commit
126ac20ccc
3
.gitignore
vendored
3
.gitignore
vendored
@ -9,5 +9,4 @@ Cargo.lock
|
|||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
/rust-lib/flowy-ast
|
/rust-lib
|
||||||
/rust-lib/flowy-derive
|
|
50
README.md
50
README.md
@ -1,38 +1,22 @@
|
|||||||
# AppFlowy client
|
[![Version](https://img.shields.io/badge/rustc-1.46+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.46.html)
|
||||||
|
![Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg)
|
||||||
* The Big Picture
|
|
||||||
* Introduce
|
|
||||||
* Goals
|
|
||||||
* Cross-platform
|
|
||||||
|
|
||||||
* Getting started
|
|
||||||
* Build
|
|
||||||
* Running
|
|
||||||
|
|
||||||
* Contributing
|
|
||||||
* First steps
|
|
||||||
* Opening issues
|
|
||||||
* Participating in discussions
|
|
||||||
* Finding something to work on
|
|
||||||
* Open your PR
|
|
||||||
* Review Process
|
|
||||||
* Getting more involved
|
|
||||||
* Organization membership
|
|
||||||
* Contributor
|
|
||||||
* Maintainer
|
|
||||||
|
|
||||||
## The Big Picture
|
|
||||||
|
|
||||||
### Introduce
|
|
||||||
|
|
||||||
### Goals
|
|
||||||
|
|
||||||
### Cross-platform
|
|
||||||
|
|
||||||
|
|
||||||
## Getting Started
|
# what is AppFlowy?
|
||||||
Read the [architecture doc](doc/architecture.md) before you started.
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
* [**Getting Started**](doc/getting_started.md)
|
||||||
|
* [**Roadmap**](doc/roadmap.md)
|
||||||
|
* [**Deep Dive AppFlowy**](doc/architecture.md)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
Read the [architecture doc](doc/architecture.md) before you started.
|
Read the [Contributing Doc](doc/contribute.md) before you want to contribute.
|
||||||
|
|
||||||
|
## Social Media
|
||||||
|
* Slack
|
||||||
|
|
||||||
|
## License
|
||||||
|
AppFlowy is under the Apache 2.0 license. See the [LICENSE](/LICENSE) file for details.
|
||||||
|
1
doc/about app flowy.md
Normal file
1
doc/about app flowy.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
[WIP]
|
@ -1,231 +1,19 @@
|
|||||||
# AppFlowy Architecture
|
# 🥳 AppFlowy System Design
|
||||||
This documentation introduces the Domain-Driven Design and the design of AppFlowy. Feel free to skip the first part
|
|
||||||
if you know what Domain-Driven Design is.
|
|
||||||
* Basic Concepts
|
|
||||||
* Layered architecture
|
|
||||||
* Domain Driven Design
|
|
||||||
|
|
||||||
* AppFlowy Design
|
* Goals of the System
|
||||||
* Overview
|
* Some Design Considerations
|
||||||
* Operation Flow
|
* High Level Design
|
||||||
* Create
|
* Component Design
|
||||||
* Read
|
|
||||||
* Update
|
|
||||||
* Delete
|
|
||||||
|
|
||||||
# Basic Concepts
|
## 🎯 Goals of the System
|
||||||
|
|
||||||
## Layered architecture
|
## 🤔 Some Design Considerations
|
||||||
The most common architecture pattern is the layered architecture pattern, known as the n-tier architecture pattern.
|
## 📜 High Level Design
|
||||||
Partition the software into `layers` to reduce the complexity. Each layer of the layered architecture pattern has a
|
## 📚 Component Design
|
||||||
specific role and responsibility.
|
|
||||||
|
|
||||||
## Domain Driven Design
|
### 📕 Component 1
|
||||||
For many architects, the process of data modeling is driven by intuition. However, there are well-formulated methodologies
|
### 📗 Component 2
|
||||||
for approaching it more formally. I recommend the [Domain-Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design)
|
### 📘 Component 3
|
||||||
and choose it as AppFlowy architecture.
|
### 📙 Component 3
|
||||||
|
|
||||||
DDD consists of four layers.
|
|
||||||
|
|
||||||
```
|
|
||||||
┌──────────────────────────────────────────────────┐ ─────────▶
|
|
||||||
│ Presentation Layer │──┐ Dependency
|
|
||||||
└──────────────────────────────────────────────────┘ │
|
|
||||||
│ │
|
|
||||||
▼ │
|
|
||||||
┌──────────────────────────────────────────────────┐ │
|
|
||||||
│ Application Layer │ │
|
|
||||||
└──────────────────────────────────────────────────┘ │
|
|
||||||
│ │
|
|
||||||
▼ │
|
|
||||||
┌──────────────────────────────────────────────────┐ │
|
|
||||||
│ Domain Layer │◀─┘
|
|
||||||
└──────────────────────────────────────────────────┘
|
|
||||||
▲
|
|
||||||
│
|
|
||||||
┌──────────────────────────────────────────────────┐
|
|
||||||
│ Infrastructure Layer │
|
|
||||||
└──────────────────────────────────────────────────┘
|
|
||||||
|
|
||||||
▲
|
|
||||||
│
|
|
||||||
Level of ├───────────────────┐
|
|
||||||
Abstraction │ Presentation │
|
|
||||||
├───────────────────┴───────┐
|
|
||||||
│ Application │
|
|
||||||
├───────────────────────────┴─────────┐
|
|
||||||
│ Domain │
|
|
||||||
├─────────────────────────────────────┴────────┐
|
|
||||||
│ Infrastructure │
|
|
||||||
└──────────────────────────────────────────────┴─────▶
|
|
||||||
Complexity
|
|
||||||
```
|
|
||||||
|
|
||||||
**Presentation**:
|
|
||||||
* Responsible for presenting information to the user and interpreting user commands.
|
|
||||||
* Consists of Widgets and also the state of the Widgets.
|
|
||||||
|
|
||||||
**Application**:
|
|
||||||
* Defines the jobs the software is supposed to do. (Shouldn't find any UI code or network code)
|
|
||||||
* Coordinates the application activity and delegates work to the next layer down.
|
|
||||||
* It doesn't contain any complex business logic but the basic validation on the user input before
|
|
||||||
passing to the other layer.
|
|
||||||
|
|
||||||
**Domain**:
|
|
||||||
* Responsible for representing concepts of the business.
|
|
||||||
* Manages the business state or delegated to the infrastructure layer.
|
|
||||||
* Self contained and it doesn't depend on any other layers. Domain should be well isolated from the
|
|
||||||
other layers.
|
|
||||||
|
|
||||||
**Infrastructure**:
|
|
||||||
|
|
||||||
This layer acts as a supporting library for all the other layers. It deals with APIs,
|
|
||||||
databases and network, etc.
|
|
||||||
|
|
||||||
DDD classifies data as referenceable objects, or entities, and non-referenceable objects, or values.
|
|
||||||
|
|
||||||
**Entity**
|
|
||||||
|
|
||||||
user, order, book, table. They are referenceable because they carry an identity which
|
|
||||||
allows us to reference them.
|
|
||||||
|
|
||||||
**Value**
|
|
||||||
|
|
||||||
email, phone number, name, age, description. They can't be referenced. They can be only included into
|
|
||||||
entities and serve as attributes. Values could be simple or could be composite.
|
|
||||||
|
|
||||||
**Aggregate**
|
|
||||||
|
|
||||||
entities can be grouped into aggregates. Aggregates can simplify the model by accessing th entire
|
|
||||||
aggregate. For instance, Table has lots of row. Each row using the table_id to reference to the
|
|
||||||
table. TableAggregate includes two entities: Table and the Row.
|
|
||||||
|
|
||||||
```
|
|
||||||
TableAggregate
|
|
||||||
┌────────────────────────────────────────────────────────────────┐
|
|
||||||
│ │
|
|
||||||
│ ┌────────────────────┐ ┌─────────────────────────┐ │
|
|
||||||
│ │struct Table { │ │struct Row { │ │
|
|
||||||
│ │ id: String, │ │ table_id: String, │ │
|
|
||||||
│ │ desc: String, │◀▶───────│} │ │
|
|
||||||
│ │} │ │ │ │
|
|
||||||
│ └────────────────────┘ └─────────────────────────┘ │
|
|
||||||
│ │
|
|
||||||
└────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
DDD also introduces `Service` and `Repository`.
|
|
||||||
|
|
||||||
**Service**
|
|
||||||
|
|
||||||
When a significant process of transformation in the domain is not a natural responsibility of an `Entity` or `Value object`, add
|
|
||||||
an operation to the model as standalone interface declared as a Service. For instance: The `Value object`, EmailAddress,
|
|
||||||
uses the function `validateEmailAddress` to verify the email address is valid or not. `Service` exists in Application, Domain and
|
|
||||||
Infrastructure.
|
|
||||||
|
|
||||||
```
|
|
||||||
class EmailAddress {
|
|
||||||
final Either<Failure<String>, String> value;
|
|
||||||
|
|
||||||
factory EmailAddress(String? input) {
|
|
||||||
return EmailAddress._(
|
|
||||||
validateEmailAddress(input),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const EmailAddress._(this.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Either<Failure<String>, String> validateEmailAddress(String? input) {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Repository**
|
|
||||||
|
|
||||||
Repository offer an interface to retrieve and persist aggregates. They hide the database or network details from the domain.
|
|
||||||
The Repository interfaces are declared in the Domain Layer, but the repositories themselves are implemented in the Infrastructure Layer.
|
|
||||||
You can replace the interface implementation without impacting the domain layer. For instance:
|
|
||||||
|
|
||||||
```
|
|
||||||
// Interface:
|
|
||||||
abstract class AuthInterface {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementation
|
|
||||||
class AuthRepository implements AuthInterface {
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
More often than not, the repository interface can be divided into sub-repository in order to reduce the complexity.
|
|
||||||
|
|
||||||
## AppFlowy Design
|
|
||||||
|
|
||||||
The AppFlowy Client consists of lots of modules. Each of them follows the DDD design pattern and using [dependency injection](https://levelup.gitconnected.com/dependency-injection-in-swift-bc16d66b038b)
|
|
||||||
to communication with other module.
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Client
|
|
||||||
┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ │
|
|
||||||
│ Module A Module B Module C │
|
|
||||||
│ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │
|
|
||||||
│ │ presentation │ Dependency │ presentation │ │ presentation │ │
|
|
||||||
│ │ │ Injection │ │ │ │ │
|
|
||||||
│ │ application ├───────────────▶│ application │ │ application │ │
|
|
||||||
│ │ │◀───────────────│ │ │ │ ◉ ◉ ◉ │
|
|
||||||
│ │ domain │ │ domain │ │ domain │ │
|
|
||||||
│ │ │ │ │ │ │ │
|
|
||||||
│ │ Infrastructure │ │ Infrastructure │ │ Infrastructure │ │
|
|
||||||
│ └───────────────────┘ └───────────────────┘ └───────────────────┘ │
|
|
||||||
│ ▲ │ │
|
|
||||||
│ │ Dependency Injection │ │
|
|
||||||
│ └─────────────────────────────────────────────────────────────┘ │
|
|
||||||
│ │
|
|
||||||
└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
Let's dig it how can I construct each module. I take `User` module for demonstration.
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
presentation Application domain Infrastructure
|
|
||||||
|
|
||||||
│
|
|
||||||
│ │
|
|
||||||
7 Data Model
|
|
||||||
┌──────────────────────────────┐ │ ┌────────────────────────┐ │ ┌───────────────────────────┐
|
|
||||||
│ │ │ │ ┌─────────────┐ │ ┌─────▶│ Repository implementation │
|
|
||||||
▼ Bloc │ 2.1 │ │ Aggregate │ │ │ │ └───────────────────────────┘
|
|
||||||
┌─────────────┐ │ ┌─────────────────┴─────┐ │ └─────────────┘ │ │ │ 4
|
|
||||||
│ Widget │ │ ┌────────┐ ┌────────┐ │ │ │ ┌────────┐ │ │ │ ▼
|
|
||||||
└─────────────┘ │ │ │ Event │ │ State │ │───┬────▶│ │ Entity │ │ │ ┌─────────────────────┐
|
|
||||||
│ │ └────────┘ └────────┘ │ │ │ │ └────────┘ │ │ │ │ Unit of Work │
|
|
||||||
│ │ └──────▲────────────────┘ │ │ ┌─────────────────┐ │ │ └─────────────────────┘
|
|
||||||
│ │ │ │ │ │ Value Object │ │ │ │ │ 5
|
|
||||||
└──────────┼────────┘ │ │ └─────────────────┘ │ │ ▼
|
|
||||||
1 │ │ └────────────────────────┘ │ │ ┌─────────────────────┐
|
|
||||||
│ │ ◈ │ │ Persistence Service │
|
|
||||||
│ │ │ contain │ │ └─────────────────────┘
|
|
||||||
│ │ ┌────────────────────┐ │
|
|
||||||
│ │ │ Service │ │ │
|
|
||||||
│ │ └────────────────────┘ │
|
|
||||||
│ 2.2 │ │
|
|
||||||
│ │ ┌───────────────────────┐ │
|
|
||||||
│ └───▶│ Repository interface │ │ │
|
|
||||||
│ └───────────────────────┘ │
|
|
||||||
│ │ │ │
|
|
||||||
│ │ 3 │
|
|
||||||
│ └───────────────┼──┘
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
1. Send event using the bloc. The bloc does not know about the `Widget`. It should communicate through events.
|
|
||||||
2. The bloc dispatching the event to the appropriate handler of the `Domain`
|
|
||||||
1. Conversion between, DTO (Data Transfer Object) to domain model and Domain Model to DTO.
|
|
||||||
2. Handling the business logic using the repository interface
|
|
||||||
3. Repository are used to store the domain model data and calls respective service to finish the jobs.
|
|
||||||
# Event-Driven
|
|
12
doc/contribute.md
Normal file
12
doc/contribute.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[WIP]
|
||||||
|
* Contributing
|
||||||
|
* First steps
|
||||||
|
* Opening issues
|
||||||
|
* Participating in discussions
|
||||||
|
* Finding something to work on
|
||||||
|
* Open your PR
|
||||||
|
* Review Process
|
||||||
|
* Getting more involved
|
||||||
|
* Organization membership
|
||||||
|
* Contributor
|
||||||
|
* Maintainer
|
243
doc/domain driven design.md
Normal file
243
doc/domain driven design.md
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
|
||||||
|
# 🍔 Domain Driven Design
|
||||||
|
|
||||||
|
For many architects, the process of data modeling is driven by intuition. However, there are well-formulated methodologies
|
||||||
|
for approaching it more formally. I recommend the [Domain-Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design)
|
||||||
|
and choose it as AppFlowy architecture.
|
||||||
|
|
||||||
|
## 💥 Layered architecture
|
||||||
|
The most common architecture pattern is the layered architecture pattern, known as the n-tier architecture pattern.
|
||||||
|
Partition the software into `layers` to reduce the complexity. Each layer of the layered architecture pattern has a
|
||||||
|
specific role and responsibility.`DDD` consists of four layers.
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────────┐ ─────────▶
|
||||||
|
│ Presentation Layer │──┐ Dependency
|
||||||
|
└──────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
▼ │
|
||||||
|
┌──────────────────────────────────────────────────┐ │
|
||||||
|
│ Application Layer │ │
|
||||||
|
└──────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
▼ │
|
||||||
|
┌──────────────────────────────────────────────────┐ │
|
||||||
|
│ Domain Layer │◀─┘
|
||||||
|
└──────────────────────────────────────────────────┘
|
||||||
|
▲
|
||||||
|
│
|
||||||
|
┌──────────────────────────────────────────────────┐
|
||||||
|
│ Infrastructure Layer │
|
||||||
|
└──────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**Presentation Layer**:
|
||||||
|
* Responsible for presenting information to the user and interpreting user commands.
|
||||||
|
* Consists of Widgets and also the state of the Widgets.
|
||||||
|
|
||||||
|
**Application Layer**:
|
||||||
|
* Defines the jobs the software is supposed to do. (Shouldn't find any UI code or network code)
|
||||||
|
* Coordinates the application activity and delegates work to the next layer down.
|
||||||
|
* It doesn't contain any complex business logic but the basic validation on the user input before
|
||||||
|
passing to the other layer.
|
||||||
|
|
||||||
|
**Domain Layer**:
|
||||||
|
* Responsible for representing concepts of the business.
|
||||||
|
* Manages the business state or delegated to the infrastructure layer.
|
||||||
|
* Self contained and it doesn't depend on any other layers. Domain should be well isolated from the
|
||||||
|
other layers.
|
||||||
|
|
||||||
|
**Infrastructure Layer**:
|
||||||
|
|
||||||
|
* Provides generic technical capabilities that support the higher layers. It deals with APIs, persistence and network, etc.
|
||||||
|
* Implements the repository interface and hiding the complexity of the Domain layer.
|
||||||
|
|
||||||
|
As you see, the `Complexity` and `Abstraction` of these layers are depicted in this diagram. Software system are composed in layers,
|
||||||
|
where higher layers use the facilities provided by lower layers. Each layer provides a different abstraction from the layer above
|
||||||
|
and below it. As a developer, we should pull the complexity downwards. Simple interface and powerful implementation(Think about the
|
||||||
|
[open](https://man7.org/linux/man-pages/man2/open.2.html) function). Another way of expressing this idea is that it is more important
|
||||||
|
for a module to have a simple interface than a simple implementation.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
▲
|
||||||
|
│
|
||||||
|
Level of ├───────────────────┐
|
||||||
|
Abstraction │ Presentation │
|
||||||
|
├───────────────────┴───────┐
|
||||||
|
│ Application │
|
||||||
|
├───────────────────────────┴─────────┐
|
||||||
|
│ Domain │
|
||||||
|
├─────────────────────────────────────┴────────┐
|
||||||
|
│ Infrastructure │
|
||||||
|
└──────────────────────────────────────────────┴─────▶
|
||||||
|
Complexity
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Data Model
|
||||||
|
DDD classifies data as referenceable objects, or entities, and non-referenceable objects, or value objects. Let's introduces
|
||||||
|
some terminologies from DDD.
|
||||||
|
|
||||||
|
**Entity**
|
||||||
|
|
||||||
|
`Entities` are referenceable because they carry an identity which allows us to reference them. e.g. user, order, book, etc.
|
||||||
|
You can use `entities` to express your business model and encapsulate them into Factory that provides simple API interface
|
||||||
|
to create Entities.
|
||||||
|
|
||||||
|
|
||||||
|
**Value Object**
|
||||||
|
|
||||||
|
`Value Object` can't be referenced. They can be only included into entities and serve as attributes. Value objects could be
|
||||||
|
simple and treat as immutable. e.g. email, phone number, name, etc.
|
||||||
|
|
||||||
|
**Aggregate**
|
||||||
|
|
||||||
|
`Entity` or `Value object` can be grouped into aggregates. Aggregates can simplify the model by accessing the entire aggregate.
|
||||||
|
For instance, Table has lots of row. Each row using the table_id to reference to the
|
||||||
|
table. TableAggregate includes two entities: Table and the Row.
|
||||||
|
|
||||||
|
```
|
||||||
|
TableAggregate
|
||||||
|
┌────────────────────────────────────────────────────────────────┐
|
||||||
|
│ │
|
||||||
|
│ ┌────────────────────┐ ┌─────────────────────────┐ │
|
||||||
|
│ │struct Table { │ │struct Row { │ │
|
||||||
|
│ │ id: String, │ │ table_id: String, │ │
|
||||||
|
│ │ desc: String, │◀▶───────│} │ │
|
||||||
|
│ │} │ │ │ │
|
||||||
|
│ └────────────────────┘ └─────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**Service**
|
||||||
|
|
||||||
|
When a significant process of transformation in the domain is not a natural responsibility of an `Entity` or `Value object`, add
|
||||||
|
an operation to the model as standalone interface declared as a Service. For instance: The `Value object`, EmailAddress,
|
||||||
|
uses the function `validateEmailAddress` to verify the email address is valid or not. `Service` exists in Application, Domain and
|
||||||
|
Infrastructure.
|
||||||
|
|
||||||
|
```
|
||||||
|
class EmailAddress {
|
||||||
|
final Either<Failure<String>, String> value;
|
||||||
|
|
||||||
|
factory EmailAddress(String? input) {
|
||||||
|
return EmailAddress._(
|
||||||
|
validateEmailAddress(input),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const EmailAddress._(this.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Either<Failure<String>, String> validateEmailAddress(String? input) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Repository**
|
||||||
|
|
||||||
|
Repository offer an interface to retrieve and persist aggregates and entities. They hide the database or network details from the domain.
|
||||||
|
The Repository interfaces are declared in the Domain Layer, but the repositories themselves are implemented in the Infrastructure Layer.
|
||||||
|
You can replace the interface implementation without impacting the domain layer. For instance:
|
||||||
|
|
||||||
|
```
|
||||||
|
// Interface:
|
||||||
|
abstract class AuthInterface {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
class AuthRepository implements AuthInterface {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
> More often than not, the repository interface can be divided into sub-repository in order to reduce the complexity.
|
||||||
|
|
||||||
|
### Relation
|
||||||
|
The diagram below is a navigational map. It shows the patterns that form the building blocks of Domain Driven Design and how they relate to each other.
|
||||||
|
![[image from here](http://uniknow.github.io/AgileDev/site/0.1.8-SNAPSHOT/parent/ddd/core/building_blocks_ddd.html)](imgs/domain_model_relation.png)
|
||||||
|
|
||||||
|
|
||||||
|
## 🔥 Operation Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
presentation │ Application domain Infrastructure
|
||||||
|
│ │
|
||||||
|
7 Data Model
|
||||||
|
┌──────────────────────────────┐ │ ┌────────────────────────┐ │ ┌─────────────────────┐
|
||||||
|
│ │ │ │ ┌─────────────┐ │ │ Network Service │
|
||||||
|
▼ Bloc │ │ │ │ Aggregate │ │ │ └─────────────────────┘
|
||||||
|
┌─────────────┐ │ ┌─────────────────┴─────┐ │ └─────────────┘ │ ▲
|
||||||
|
────────▶ Widget │ │ ┌────────┐ ┌────────┐ │ 2 │ ┌────────┐ │ │ │ 6
|
||||||
|
└─────────────┘ │ │ │ Event │ │ State │ │────┬───▶│ │ Entity │ │ ┌─────────────────────┐
|
||||||
|
User │ │ └────────┘ └────────┘ │ │ │ │ └────────┘ │ │ │ Persistence Service │
|
||||||
|
interaction │ │ └──────▲────────────────┘ │ │ ┌─────────────────┐ │ └─────────────────────┘
|
||||||
|
│ │ │ │ │ │ Value Object │ │ │ ▲
|
||||||
|
└──────────┼────────┘ │ │ └─────────────────┘ │ │ 5
|
||||||
|
1 │ │ └────────────◈───────────┘ │ ┌─────────────────────┐
|
||||||
|
│ │ │contain │ Unit of Work │
|
||||||
|
│ │ ┌────────────────────┐ │ └─────────────────────┘
|
||||||
|
│ │ │ Service │ ▲
|
||||||
|
│ │ └────────────────────┘ │ │
|
||||||
|
│ │ │ 4
|
||||||
|
│ │ Repository │ │
|
||||||
|
│ │ ┌─────────────────────────────────────────────┴───────────────┐
|
||||||
|
│ │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ 3 ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │
|
||||||
|
│ └───┤ Interface ────▶ Implementation │
|
||||||
|
│ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
|
||||||
|
│ └─────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
1. Widget accepts user interaction and transfers the interactions into specific events. The events will be send to the Application layer,
|
||||||
|
handled by the specific `bloc`. The `bloc` send the states changed by the events back to the widget, and finally the `Widget` update
|
||||||
|
the UI according to the state. The pattern is depicted in this diagram. (More about the flutter [bloc](https://bloclibrary.dev/#/coreconcepts?id=bloc))
|
||||||
|
```
|
||||||
|
┌──────────── State ────────────┐
|
||||||
|
│ │
|
||||||
|
▼ Bloc │
|
||||||
|
┌─────────────┐ ┌─────────────┼─────────┐
|
||||||
|
────────▶│ Widget │ │ ┌────────┐ ┌┴───────┐ │
|
||||||
|
└─────────────┘ │ │ Event │ │ State │ │
|
||||||
|
User interaction │ │ └────────┘ └────────┘ │
|
||||||
|
│ └───────────────────────┘
|
||||||
|
│ ▲
|
||||||
|
│ │
|
||||||
|
└────────── Event ────────────┘
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
2. The `bloc` process the events using the services provided by the `Domain` layer.
|
||||||
|
1. Convert DTO (Data Transfer Object) to domain model and Domain Model to DTO.
|
||||||
|
2. Domain model is the place where all your business logics, business validation and business behaviors will be implemented.
|
||||||
|
The Aggregate Roots, Entities and Value Objects will help to achieve the business logic.
|
||||||
|
3. Calling repositories to perform additional operations. The repositories interfaces are declared in `Domain`, implemented in `Infrastructure`.
|
||||||
|
You can reimplement the repository interface with different languages, such as `Rust`, `C++` or `Flutter`. etc.
|
||||||
|
```
|
||||||
|
Domain Infrastructure
|
||||||
|
|
||||||
|
Repository A │
|
||||||
|
┌────────────────────────────┼────────────────────────────────┐
|
||||||
|
│ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │
|
||||||
|
│ Interface ──┼─▶ Implementation │
|
||||||
|
│ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
|
||||||
|
└────────────────────────────┼────────────────────────────────┘
|
||||||
|
Repository B │
|
||||||
|
┌────────────────────────────┼────────────────────────────────┐
|
||||||
|
│ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │
|
||||||
|
│ Interface ──┼─▶ Implementation │
|
||||||
|
│ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │
|
||||||
|
└────────────────────────────┴────────────────────────────────┘
|
||||||
|
```
|
||||||
|
4. Responsibility of [Unit of Work](https://martinfowler.com/eaaCatalog/unitOfWork.html) is to maintain a list of objects affected by a
|
||||||
|
business transaction and coordinates the writing out of changes and the resolution of concurrency problems((No intermediate state)).
|
||||||
|
If any one persistence service fails, the whole transaction will be failed so, roll back operation will be called to put the object
|
||||||
|
back in initial state.
|
||||||
|
|
||||||
|
5. Handling operations (INSERT, UPDATE and DELETE) with SQLite to persis the data.
|
||||||
|
6. Saving or querying the data in the cloud to finish the operation.
|
0
doc/getting_started.md
Normal file
0
doc/getting_started.md
Normal file
Binary file not shown.
Before Width: | Height: | Size: 62 KiB |
BIN
doc/imgs/domain_model_relation.png
Normal file
BIN
doc/imgs/domain_model_relation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
1
doc/roadmap.md
Normal file
1
doc/roadmap.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
[WIP]
|
1
doc/why flutter and rust.md
Normal file
1
doc/why flutter and rust.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
[WIP]
|
Loading…
Reference in New Issue
Block a user