Ласкаво просимо до серії статей, в яких я пишу про C# та ASP.NET. Сподіваюся, вони будуть корисними і знайдуть свого читача. Приємного читання. 😊
Clean Architecture (Чиста Архітектура) — це підхід до архітектури програмних проєктів, який забезпечує гнучкість, тестуваність та стійкість. Цю архітектуру у 2012 році представив Роберт С. Мартін (Uncle Bob), і вона дозволяє зосередити увагу на бізнес-логіці проєкту та правильно управляти залежностями. У цій статті ми детально розглянемо концепцію Clean Architecture, її основні принципи та те, як її реалізувати за допомогою .NET Core. Також на реальних прикладах коду ми покажемо, як на практиці застосовувати чисту архітектуру.
1. Clean Architecture: Що це таке?
Clean Architecture — це модель проєктування, яка управляє залежностями між шарами проєкту та гарантує, що бізнес-логіка залишається в центрі уваги.
Основна мета — зробити різні шари системи незалежними один від одного, щоб зміни були менш витратними та легшими для впровадження.
Основні шари Clean Architecture (Чистої Архітектури):
- Entities (Вартики): Об'єкти, які представляють бізнес-логіку додатку. Цей шар містить правила системи та структури даних.
- Use Cases (Використання Сценаріїв): Логіка додатку, яка виконує бізнес-правила. Взаємодіючи з шаром Entities, цей шар задовольняє вимоги та запити користувача.
- Interface Adapters (Адаптери Інтерфейсу): Шар, який перетворює дані у формат, придатний для користувацького інтерфейсу або зовнішніх систем. API, контролери MVC або адаптери служб знаходяться в цьому шарі.
4.
Frameworks & Drivers (Фреймворки та Драйвери): Зовнішні інструменти та сервіси, такі як бази даних, фреймворки UI тощо.
Правило залежностей між шарами Clean Architecture (Чистої Архітектури):
Залежності повинні рухатися лише з центру до зовнішніх шарів. Тобто, зовнішні шари (UI, Frameworks) можуть залежати від внутрішніх (Entities, Use Cases), але навпаки бути не повинно. Має бути підхід від специфічного до загального.
2. Переваги Clean Architecture (Чистої Архітектури)
- Тестованість: Оскільки бізнес-логіка та інші шари незалежні, ви можете легко тестувати окремі компоненти.
- Незалежність: Бізнес-логіка не залежить від жодного фреймворку чи технології. Завдяки цьому система легко переноситься на інші платформи.
- Легкість у підтримці: Оскільки між шарами є чіткий поділ, код стає зрозумілішим і легшим для підтримки. Легше знаходити та виправляти помилки.
- Гнучкість: Легко додавати нові функціональності або змінювати існуючу структуру. Адже завдання кожного шару чітко визначено.
5.
Повторне Використання: Бізнес-логіка та сценарії використання можуть бути повторно використані в різних проєктах.
3. Реалізація Clean Architecture (Чистої Архітектури) з .NET Core
Крок 1: Створення Структури Проєкту
Для модульності проєкту в чистій архітектурі використовуються кілька проєктів. Один з рекомендованих варіантів структури виглядає наступним чином:
MyApp
├── MyApp.Core (Entities та Use Cases)
├── MyApp.Application (Interface Adapters)
├── MyApp.Infrastructure (Frameworks & Drivers)
├── MyApp.API (Сервер та API)
Крок 2: Створення Шару Entities
namespace MyApp.Core.Entities
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
}
Пояснення:
Тут ми створили сутність під назвою Product. Ця сутність буде містити інформацію про продукти в нашій системі, включаючи ID, назву та ціну.
Цей клас розташовується в шарі Entities і безпосередньо представляє нашу бізнес-логіку.
Крок 3: Створення Шару Use Cases
namespace MyApp.Core.UseCases
{
public class CalculateDiscount
{
public decimal Execute(decimal price, decimal discountRate)
{
if (discountRate < 0 || discountRate > 1)
throw new ArgumentException("Невірна ставка знижки");
return price * (1 - discountRate);
}
}
}
Пояснення:
На цьому кроці ми створили сценарій використання для обчислення знижки. Клас CalculateDiscount містить бізнес-правила. Ми написали метод, який приймає ціну та ставку знижки та повертає нову ціну.
Бізнес-правила знаходяться в шарі Use Cases, який є центром Clean Architecture (Чистої Архітектури).
Крок 4: Створення Шару Interface Adapters
using MyApp.Core.Entities;
using MyApp.Core.UseCases;
namespace MyApp.Application.Services
{
public class ProductService
{
private readonly CalculateDiscount _calculateDiscount;
public ProductService(CalculateDiscount calculateDiscount)
{
_calculateDiscount = calculateDiscount;
}
public decimal GetDiscountedPrice(Product product, decimal discountRate)
{
return _calculateDiscount.Execute(product.Price, discountRate);
}
}
}
Пояснення:
Тут ми написали сервіс, який з'єднує бізнес-логіку з даними, отриманими від користувача. ProductService залежить від класу CalculateDiscount, який реалізує бізнес-правила.
Цей сервіс обробляє запити з зовнішнього світу відповідно до бізнес-логіки і повертає результат.
Крок 5: Створення Шару Infrastructure
using MyApp.Core.Entities;
namespace MyApp.Infrastructure.Repositories
{
public class ProductRepository
{
private readonly List _products = new();
public IEnumerable GetAllProducts() => _products;
public void AddProduct(Product product) => _products.Add(product);
}
}
Пояснення:
На цьому кроці ми створили репозиторій для зберігання інформації про продукти. ProductRepository зберігає продукти в списку і надає функції для додавання елементів до списку або повернення всього списку.
Цей шар охоплює зовнішні компоненти, такі як бази даних або зовнішні джерела даних.
Крок 6: Створення Шару API
using Microsoft.AspNetCore.Mvc;
using MyApp.Application.Services;
using MyApp.Core.Entities;
namespace MyApp.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly ProductService _productService;
public ProductsController(ProductService productService)
{
_productService = productService;
}
[HttpPost]
public IActionResult AddProduct([FromBody] Product product, decimal discountRate)
{
var discountedPrice = _productService.GetDiscountedPrice(product, discountRate);
return Ok(new { OriginalPrice = product.Price, DiscountedPrice = discountedPrice });
}
}
}
Пояснення:
На цьому етапі ми написали контролер, який управляє API endpoint (точками доступу API).
ProductsController отримує запити від користувача та викликає ProductService, який реалізує бізнес-логіку. API приймає продукт та ставку знижки і повертає знижку на продукт. Цей шар забезпечує зв'язок між зовнішнім світом та системою.
Крок 7: Управління Залежностями Між Шарами
Додайте залежності у файл Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton();
builder.Services.AddSingleton();
var app = builder.Build();
app.MapControllers();
app.Run();
Пояснення:
На цьому кроці ми налаштували інжекцію залежностей (Dependency Injection) у файлі Program.cs:
builder.Services.AddSingleton();
— ми зареєстрували клас CalculateDiscount як сервіс. Це забезпечує використання одного екземпляра цього класу на всьому шляху виконання програми. Тепер ми можемо отримувати доступ до цього класу у будь-якому місці, яке потребує бізнес-логіки.
2.
builder.Services.AddSingleton(); `ProductService клас додано як єдиний екземпляр. Цей сервіс взаємодіє з іншими класами, застосовуючи бізнес-логіку до даних, що надходять ззовні.app.MapControllers();
Ми додали всі Controller класи, що ми написали для API, до конвеєра додатка. Це дозволяє обробляти вхідні HTTP запити відповідними контролерами.app.Run();
Запускає додаток і дозволяє API почати приймати запити.
Підсумок:
Цей крок використовує Dependency Injection для зв'язування різних шарів і завершує побудову Clean Architecture. Ми правильно керували залежностями між всіма шарами, і всі компоненти додатка стали взаємно сумісними. Тепер наша система має гнучку, тестовану та стійку архітектуру.
4. Реальні застосування Clean Architecture
1.
E-Commerce додатки: Забезпечують багатошарову архітектуру для управління замовленнями, обробки платежів та перевірки користувачів.
2. Корпоративні системи: Роблять бізнес-логіку незалежною від технологій, що забезпечує довгострокові рішення.
3. Мікросервіси: Створюють чіткі межі між різними сервісами, спрощуючи процеси розробки та обслуговування.
5. Результат
Clean Architecture є відмінним рішенням для створення міцної основи в програмних проектах. У цій статті ми розглянули основні концепції Clean Architecture, його переваги та як його застосовувати за допомогою .NET Core.
З цією інформацією ви зможете створити архітектурний дизайн, що забезпечить гнучкість, тестованість та сталий розвиток для ваших проектів. Для детальнішого ознайомлення, рекомендуємо прочитати книгу Clean Architecture від Uncle Bob. Дякую за ваш час, сподіваюся, що це було корисно, і до нових зустрічей у майбутніх читаннях.🙏
Program.cs
файлі додайте залежності:
Перекладено з: Clean Architecture Nedir? .NET Core ile Mimari Tasarım