[iOS] - Giải thích và ví dụ Clean Architecture trong iOS

I. Cái nhìn tổng quan:


1. Domain: Chứa những protocol định nghĩa các feature và các entities.

Phần Domain cơ bản mô tả các phần chính trong App của bạn, chức năng nhiệm vụ là gì (Entities, UseCase, v.v). Nó không hề phụ thuộc vào UIKit hay bất kì framework cố định nào và nó cũng không có các phần implementation ngoại trừ các entities.

2. Platform: Chứa những implementation của Domain và Object của các specific Database.

 Đây sẽ là phần implementation của Domain trong những platform specific như DatabasePlatform, NetworkPlatform. Nó sẽ ẩn đi những implementation details. Ví dụ như phần Database implementation không quan tâm bên trong dùng CoreData hay Realm.

3. Application: Chứa những code UI như ViewControllers hay ViewModel

Phần Application chịu trách nhiệm truyền thông tin cho User và sử dụng user input. Nó có thể được sử dụng với pattern của bạn (MVVM, MVC, MVP). Đây là nơi để bạn đặt UIViews, UIViewControllers. Ở ví dụ dưới đây, bạn sẽ thấy ViewControllers hoàn toàn độc lập với Platform. Trách nhiệm duy nhất của 1 View Controller là để bind UI đến Domain để thực hiện mọi việc. Trong ví dụ dưới đây, ta sẽ dùng cùng View Controller cho Realm và CoreData.

II. Chi tiết:

Để thực thi các module thì Domain, Platform và Application được chia thành các targets riêng biệt trong App. Điều này cho phép chúng ta tận dụng được tính chất của Access Control (internal) trong Swift để tránh việc bị lộ ra các types mà ta không muốn show ra.

Trong dự án thực tế cũng vậy, ta chia ra thành 3 target lớn rồi bắt đầu chia ra từng phần nhỏ. Sau đó Import vào mà dùng. Ở đây, ta có 1 từ đó là useCase, hiểu nôm na là một feature riêng biệt của ứng dụng, một useCase có thể hoặc không thể được bắt bắt đầu bởi user input. 

Bạn có thể thấy cách tổ chức code rõ ràng như hình trên, có 1 điều: có nên bỏ hết những platform riêng biệt vào 1 folder Platform chung hay không là tuỳ mỗi người.

III. Phân tích code:

1. Domain: (sẽ chứa các entities, useCases và usesCaseProvider)


- Entities được Implement như bình thường giống như Object mà các bạn khai báo trước giờ: 

public struct Post {
    public let uid: String
    public let createDate: Date
    public let updateDate: Date
    public let title: String
    public let content: String
}

- UseCases là những protocols mà làm 1 việc cụ thể nào đó, ví dụ như protocol dưới đây, nó thực thi posts và save.

public protocol PostsUseCase {
    func posts() -> Observable<[Post]>
    func save(post: Post) -> Observable
}

- UseCaseProvider là 1 service locator. Service Locator là gì mình sẽ viết ở những bài sau. Ở ví dụ hiện tại, nó giúp ẩn đi những implemenation cụ thể của các useCases.

2. Platform:


Trong 1 số trường hợp, ta không thể dùng structs trong Swift cho Domain của mình vì những yêu cầu từ DB Framework (ví dụ như Realm hay CoreData). 

Ngoài ra nó còn chứa những phần implementations cụ thể của UseCases của bạn trong phần Domain. Repository là nơi chứa Database local với những phần query cơ bản như CRUD. 

Như bạn thấy, các implementations cụ thể này là internal, bởi vì ta không muốn lộ ra các dependencies của mình. Cái duy nhất mà để cho bên ngoài truy cập được từ Platform trong ví dụ này là implementation UseCaseProvider. Lý do tại sao? Mình sẽ giải thích sau.

3. Application:

Đây là phần mà bạn sử dụng pattern của mình để binding, xử lý logic code giữa ViewController và ViewModel. Phần này các bạn đọc những bài viết về cách dùng RxSwift kết hợp MVVM để hiểu thêm.

==

Bài viết được dịch từ https://github.com/sergdort/CleanArchitectureRxSwift 

Bình luận
* Các email sẽ không được công bố trên trang web.
I BUILT MY SITE FOR FREE USING