[Tin tức] Chia sẻ kiến trúc – Giải thích Clean Architecture



Trong video này mình chủ yếu chia sẻ về ý tưởng, triết lý và các đặc tính quan trọng của Clean Architecture. Một lỗi sai mình thường thấy nhất là các bạn hiểu sai cái Dependency Rule nên phần nào gây nhầm lẫn và khó triển khai.

1. Triết lý của Clean Architecture giống với Hexagonal và Onion Architecture: cô lập và lấy business logic làm trọng tâm (có thể gọi là Domain). Bên ngoài giao tiếp thông qua các Ports: Input và Output.

2. Các vòng tròn ở ngoài cùng là chi tiết nhất (low-level/details), trong cùng là high level (trừu tượng).

3. Cái “mũi tên” trong ảnh Clean Architecture không phải là “call direction” mà là “dependency direction”. Bởi vì:

4. Clean Architecture sử dụng Dependency Inversion (DI) – chữ D trong SOLID.
– High level không phụ thuộc vào low level, chúng lệ thuộc abstraction.
– Abstraction không lệ thuộc vào implements/details của nó.

Từ đó các thay đổi từ các tầng low-level (chi tiết) không gây ảnh hưởng gì đến Domain ở trong. Và domain dễ dàng test, maintain một cách độc lập.

Khi implement Clean Architecture thì cấu trúc thư mục, cách phân chia package sao cũng được, miễn thoả các đặc tính trên.

Thường để đảm bảo DI, các SE kinh nghiệm thường khai báo các interfaces cần thiết ở trong domain, sau đó viết business logic, mocktesting các kiểu xong hết mới đi xử các tầng details bên ngoài: Như DB, HTTP Handlers,…

Cách này có thể gọi là Use Case first hoặc Doman Driven. Tuy nhiên để gọi là DDD và làm đúng và đủ thì còn khá nhiều thứ nữa.

Có thời gian mình sẽ nói DDD sau!!!

16 bình luận về “[Tin tức] Chia sẻ kiến trúc – Giải thích Clean Architecture”

  1. Em chào Anh, Anh có thể giải thích giúp em Presenters layer implement cái gì được không ạ?
    +, Flow từ: UI -> presenters -> use case
    Em không biết presenters có chức năng gì trong flow này.
    Cùng với đó là flow of control ở sơ đồ góc dưới dùng bên phải với ạ:
    +, Controller -> use case interactor -> presenters.
    Vì theo dependence rule thì low level sẽ depend vào high level nên em không hiểu cái flow này đi như nào cả.
    Em mới tìm hiểu về clean nên mong Anh thông cảm vì ngôn từ có thể không được chuẩn chỉnh ạ.
    Em cảm ơn Anh nhiều.

    Bình luận
  2. cho e hỏi thêm với ạ, ở phút 9:00 em thấy ý tưởng đặt `IRepository` ở tầng usecase của a rất hay. nhưng nếu làm theo cách này thì tầng data ở dưới phải import ngược lên module usecase => data layer nó phụ thuộc vào usecase layer rồi đúng k ạ, theo e ĐÚNG phải là tầng usecase phụ thuộc vào tầng data ạ. Có cách nào giải quyết vấn đề này không ạ?

    Bình luận
  3. dạ cho e hỏi ạ. cái dialog 4:40 . trường hợp trong project chỉ có duy nhất một 1 implementation của contract `IUseCase` và tầng Data cũng chỉ có duy nhất 1 implementation của `IRepository` thì có nhất thiết phải áp dụng DI, tạo ra 2 interface chỗ này không ạ? em thấy đang phức tạp hoá 1 vấn đề đơn giản ạ. Vì theo em hiểu mình dùng Interface để có thể thay đổi một cách dynamic at runtime mà trong project chỉ có duy nhất 1 implementation của contract đó thì "WITHOUT DI" chỗ này cũng giải quyết tốt vấn đề ạ!

    Bình luận
  4. interface IRepositoryPlayer {
    getAllPlayer: () => Promise<string[]>;
    }
    class RepositoryPlayer implements IRepositoryPlayer {
    getAllPlayer() {
    // get from DB
    return Promise.resolve(["thuong"]);
    }
    }
    class PlayerService {
    constructor(private repository: IRepositoryPlayer) {}
    }
    const repoPlayer = new RepositoryPlayer();
    const player = new PlayerService(repoPlayer);
    Theo em hiểu cái đoạn 9:11 sẽ là ntn đúng k a ạ ?.

    Bình luận

Viết một bình luận

bahis10bets.com betvole1.com casinomaxi-giris.com interbahis-giris1.com klasbahis1.com mobilbahisguncelgiris1.com piabetgiris1.com tipobettgiris.com tumbetgiris1.com betboro 1xbet giriş
bahis10bets.com betvole1.com casinomaxi-giris.com interbahis-giris1.com klasbahis1.com mobilbahisguncelgiris1.com piabetgiris1.com tipobettgiris.com tumbetgiris1.com betboro 1xbet giriş
antalya bayan escort
antalya bayan escort
antalya bayan escort