Skip to content

Commit

Permalink
Merge pull request #25 from DouglasbDev/feat/arch
Browse files Browse the repository at this point in the history
Feat/arch
  • Loading branch information
jacobaraujo7 committed Feb 6, 2024
2 parents 95a5084 + b3beec2 commit 119addf
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 210 deletions.
299 changes: 89 additions & 210 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,253 +1,132 @@
# YuNO Architecture
# Arquitetura - MiniCore

This architecture aims to clearly separate responsibilities into layers, making code maintenance, testability, and scalability easier. Each layer has a specific purpose, and dependencies are organized so that business logic is not tightly coupled to technical implementation, allowing flexibility and ease of system evolution.
**Objective**: Propose a simplified and easily understandable architecture, focusing on the FrontEnd. The proposed structure is based on three distinct layers: User Interactor, Adaptation, and External.

<img src="assets/YuNO-Arch.png" width="512" alt="Achitecture diagram"/>
### Layers

## 1. Layers
**User Interactor**: Should be responsible for declaring the inputs, outputs, and interactions of the application.

### 1.1 Public
**Adaptation**: Should be responsible for translating and facilitating communication between the User Interactor and External layers.

Encompasses all pages and subpages of the application.
**External**: Should be responsible for handling information external to your application.
<br>
<br>

- **Pages:**
- Represents the user interface layer.
- Should be decoupled as much as possible from non-essential UI packages.
- **Widgets:**
- Contains specific visual components for a single page.
<p align="center">
<img src="assets/vai.png" width="512" alt="Achitecture diagram"/>
</p>

### 1.2 Interactor
<br>
<br>

Encompasses business rules and yours interfacer.
<p align="center">
<img src="assets/volta.png" width="512" alt="Achitecture diagram"/>
</p>

- **Atoms:**
- Small building blocks representing atomic units of functionality.
- **Actions:**
- Represents actions that can be performed in the system.
- **Interfaces of Repositories and Services:**
- Defines contracts for interactions with data layers.
### Limits

### 1.3 Data
Within the established architectural boundaries, it is highlighted that the User Interactor layer should not have direct access to the External layer. To overcome this restriction, the Adaptation layer acts as an intermediary, facilitating communication between the User Interactor and External layers.

Encompasses the execution of business rules.
With the aim of enhancing development efficiency and flexibility, the architecture ensures low coupling through a clear separation of responsibilities in each layer.

- **Implementations:**
- **Repositories and Services:**
- Contains concrete implementations of contracts defined in the Interactor layer.
- Responsible for interacting with external data sources such as databases or APIs.

### 1.4 Core
## Architecture Structure

Encompasses global data for the application.
### UI (User Interface)
This layer must contain the visual elements of the application.

- **Themes:**
- Defines visual styles and themes for the application.
- **Assets:**
- Stores static resources such as images, icons, etc.
- Every type of asset requires a specific file, with its names listed and pre-cached in a function.
- **Widgets:**
- Reusable components that can be used in different parts of the application.
- **Other Global Data:**
- Includes other elements essential for the global operation of the application.
### Interactor
This layer should encompass the states or reactivities of the application, the representation of business rules, abstractions for communication between the other layers, and the operations executed by its UI.

## 2. Nomenclatures
- #### Atoms:
They must store an application state.

This section outlines the naming conventions for different components of our application including widgets, actions, atoms, repositories, and services.
- #### Actions:
They must have the purpose of changing the application states.

### 2.1 Widgets
- #### DTO:
Data Transfer Object is a design pattern used to transfer data between layers.

### Guidelines for Widget Naming
- #### Models:
They represent business rules.

- **Suffix "Widget":** All widget classes should consistently use the "Widget" suffix. This makes it easier to identify them in the codebase.
- **Clarity and Consistency:** The name should clearly reflect the widget's functionality.
- **Example:** `login_button_widget.dart`
- #### Interfaces:
They must contain interfaces to achieve loose coupling, reducing direct dependency and providing easy replacement of implementations.

## Data
They must interact with external sources.

```dart
class LoginButtonWidget extends StatelessWidget { }
```

### 2.2 Actions

### Guidelines for Action Naming

- **Verb-Noun Format:** Names of actions should typically follow a verb-noun format, indicating what the action does.
- **Descriptive:** Ensure the name gives a clear indication of its purpose.
- **Example:** `config_action.dart`

```dart
Future<T> fetchConfig() {}
Future<T> saveConfig() {}
```

### 2.3 Atoms

### Guidelines for Atom Naming

- **Descriptive and Concise:** Atom names should be concise yet descriptive enough to indicate their role and usage.
- **Component Specific:** Name atoms based on their functionality or the data they handle.
- **Example:**
`config_atom.dart`

```dart
final configState = Atom<T>();
```

### 2.4 Repositories

### Guidelines for Repository Naming

- **Noun Format:** Repository names should be clear, concise nouns.
- **Reflect Data Model:** They should closely reflect the data model or resource they are associated with.
- **Example:**
`game_repository.dart`

```dart
class GameRepository { }
```

### 2.5 Services

### Guidelines for Service Naming

- **Noun or Verb-Noun Format:** Service names can be nouns or verb-noun combinations, indicating the service provided.
- **Purpose-Clear:** The name should clearly reflect the functionality or the domain of the service.
- **Example:**
`authentication_service.dart`

```dart
class AuthenticationService { }
```

This structured approach provides a clear and organized set of naming conventions across different elements of the application, ensuring consistency and clarity in the codebase.

## 3. Tests

Testing is a crucial part of software development. It ensures code quality and functionality, and helps in maintaining the software over time. Our testing approach adheres to the triple-A pattern (Arrange, Act, Assert) for its clarity and structure.

For an in-depth understanding, refer to this article on the [Triple-A Pattern](https://medium.com/@pjbgf/title-testing-code-ocd-and-the-aaa-pattern-df453975ab80).

### Example
- #### Adapter:
There must be adaptations to ensure that external data follows the standards defined by the application.

```dart
test('should execute a sum correctly', () {
- #### Tratamento de erros:
As a good practice, we must handle errors in our application, ensuring stability and reducing the occurrence of failures.

- #### Repository:
It must contain the concrete class, coming from the abstraction, for communication between layers.

- #### Service:
It must contain the concrete class, coming from the abstraction, for communication between layers.

// arrange
int number1 = 2;
int number2 = 1;
## Core
It must contain global and reusable information for all layers of the application.

// act
final result = sumFunction(number1, number2);
## Benefits of Using MiniCore Architecture:

// assert
expect(result, 3);
- #### Ease of Understanding:
It provides a clear and intuitive structure, making the code easier for developers to understand.

});
```
- #### Maintainability:
Layering and clarifying responsibilities makes the code easier to maintain and update.

### 3.1 Test Description
- #### Code Scalability:
The architecture is designed to handle application growth, ensuring it can scale effectively.

The description of each test should clearly articulate the expected outcome based on the specific action or condition being tested. Avoid generic or obvious descriptions. Instead, focus on what is being verified in each test case.
- #### Easy Access to Global Variables and Methods:
Facilitates access to global variables and methods, promoting efficient communication between different parts of the system.

### Guidelines for Test Descriptions
- #### Facilitates Testing (Without the Need to Mock the Atoms):
Simplify testing by eliminating the need to simulate or mock Atoms, making the testing process more efficient and less complex.

- Clearly state the purpose of the test.
- Describe the specific condition or scenario.
- Indicate the expected result or behavior.
Another important point will be the global state, and with this, we gain:

### Examples of Good Descriptions
Universal Accessibility: The global state allows data to be accessed from anywhere in the application. This can be useful when you need to share information between different parts of the user interface or across multiple pages.

- Correct: "should return the sum of two numbers when both inputs are positive".
- Avoid: "Should return a result".
Reduced Complexity: Instead of passing data through various components as parameters, the use of a global state can simplify the code, making it more readable and easier to understand.

### 3.2 Test Grouping
Ease of Maintenance: By centralizing the state in a global location, it becomes easier to maintain and modify the application state. This can facilitate bug resolution and the implementation of new features.

Grouping tests is essential for organization and readability, especially in large codebases. Group names should correspond to the class or functionality they are testing, with an optional method name if applicable. Use " | " (space, pipe, space) at the end of each group name for clarity.
Improved Performance: Depending on the implementation, a well-managed global state can lead to better performance, especially compared to approaches where data needs to be passed through many components.

### Guidelines for Test Grouping

- Group tests by functionality or class.
- Use descriptive names that reflect the group's purpose.
- Optionally include the specific method being tested.
<br>

### Example of Action Test Group
By adopting the MiniCore architecture, developers gain a more robust, efficient, and easily maintainable system development, promoting a more positive and sustainable development experience.

```dart
group('SaveGameAction | ', () {
// Tests for SaveGameAction
});
```
## Examples

### Example of Repository Test Group
According to the proposed architecture, the folder structure is defined.

```dart
group('AndroidAppsRepository.openAppSettings | ', () {
// Tests for AndroidAppsRepository.openAppSettings
});
```

## 3.3 Additional Best Practices

- **Test Isolation:** Ensure each test is independent and can run alone.
- **Code Coverage:** Aim for high test coverage, but prioritize meaningful tests over merely inflating coverage metrics.
- **Mocking and Stubbing:** Use mocks and stubs where necessary to isolate the unit of test.

Remember, good tests not only check for correct outcomes but also contribute to the overall quality and maintainability of the software.

## 4. Localizations

Localization is key to making an application accessible and user-friendly to a global audience. This section provides guidelines and best practices for implementing localizations.

### 4.1 Implementing Localizations

### Steps for Implementation

#### 4.1.1 Defining localization files

Create a JSON file in the i18n folder, this file should be named `xx.json` where xx should be replaced with the locale, for example: en_US.json. These files must contain key-value pairs for strings in different languages.

**Example of content to pt_BR.json file:**

```json
{
"home": "Início",
"apps": "Apps",
"settings": "Configurações",
"favorite": "Favoritar",
"play": "Jogar",
"syncing": "Sincronizando",
"search_a_game": "Pesquise um jogo",
"platforms": "Plataformas",
"preferences": "Preferencias",
"feedback": "Feedback",
"about": "Sobre",
"add_platorm": "Adicionar Plataforma"
}
.
└── app/
├── public/
│ └── pages/
├── core/
│ ├── assets/
│ ├── themes/
│ └── widgets/
├── data/
│ ├── adapters/
│ ├── repositories/
│ └── services/
└── interactor/
├── atoms/
├── actions/
├── dtos/
├── models/
├── repositories/
└── services/
```

#### 4.1.2 Locale Configuration

Configure the list of supported locales in the app_widget.dart file.

#### 4.1.3 Loading Localized Data

We use the `localization` package to load and retrieve localized data based on the current locale.

#### 4.1.4 Dynamic Text Replacement

Implement dynamic text replacement in the UI using localized strings.

#### 4.1.5 Fallback Locale

Set up a fallback locale for scenarios where the user's locale doesn't match any supported locales.

### 4.2 Best Practices for Localizations

- **Key Consistency:** Ensure consistency in the naming of keys across different localization files.

- **Regular Updates:** Regularly update localization files whenever there are changes in the text of the application.

- **Testing for Different Locales:** Test the application in different languages to ensure that the translations fit well in the UI and are contextually accurate.

- **Cultural Considerations:** Pay attention to cultural nuances in translations to avoid misunderstandings or offense.

- **Automated Tools and Human Review:** Consider using automated translation tools for efficiency, but always have translations reviewed by native speakers for accuracy and context.
See some [examples](https://github.com/FelCarv01/mini-core-examples).
Binary file added assets/vai.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/volta.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 119addf

Please sign in to comment.