Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
[Android] Clean Architecture
Clean Architecture
Việc xây dựng 1 kiến trúc nền tốt thật sự quan trọng cho ứng dụng để scale lên một cách đơn giản. Trước đây thì mình cực kì không thích thằng clean này đơn giản vì nó phải code nhiều quá, mà ghét của nào trời trao của đấy. Hiện tại thì sắp nhảy vào một dự án sử dụng clean. Trong bài viết này, mình sẽ tìm hiểu và "thích" nó nhé.
Clean architecture ?
Clean architecture hay còn gọi là kiến trúc sạch được đề xuất vào năm 2012 bởi Robert C. Martin. Hãy đọc thật kĩ blog này nhé, nếu không bạn có thể tẩu hỏa nhập ma đấy.
Why ?
Tại sao lại tiếp cận theo hướng kiến trúc sạch ?
- Tách biệt hoàn toàn các tầng (layer) với nhau với nhiệm vụ riêng biệt giúp cho việc chỉnh sửa dễ dàng hơn.
- Tăng tính trừu tượng
- Tránh ràng buộc
- Dễ dàng kiểm thử
Layers ?
- Domain Layer : chịu trách nhiệm thực thi các logic độc lập với các layer khác. Layer này chỉ bao gồm các mã kotlin thuần túy, không bao gồm sự phụ nào của Android Framework ở đây.
- Data Layer : chịu trách nhiệm phân chia data cần thiết cho app bằng cách implement các interface được phát ra từ tầng domain.
- Presenter Layer : chứa cả Domain và Data layer, chịu trách nhiệm thực thi các logic giao diện.
What is Domain layer ?
- Domain là tầng chung nhất trong 3 tầng. Nó sẽ kết nối tầng presenter với tầng data. Đây là tầng nơi các business logic của ứng dụng được thực thi.
UseCases
Đóng gói thực hiện các case của hệ thống theo đúng cái tên của nó. Mỗi usecase sẽ mô tả một chức năng riêng biệt.
class GetNewsUseCase(private val transformer: FlowableRxTransformer<NewsSourcesEntity>,
private val repositories: NewsRepository): BaseFlowableUseCase<NewsSourcesEntity>(transformer){
override fun createFlowable(data: Map<String, Any>?): Flowable<NewsSourcesEntity> {
return repositories.getNews()
}
fun getNews(): Flowable<NewsSourcesEntity>{
val data = HashMap<String, String>()
return single(data)
}
}
Repositories
Repos chỉ định các chức năng được yêu cầu tương ứng với các usecase chỉ định.
interface NewsRepository {
fun getNews(): Flowable<NewsSourcesEntity>
fun getLocalNews(): Flowable<NewsSourcesEntity>
fun getRemoteNews(): Flowable<NewsSourcesEntity>
}
What is Data Layer ?
Tầng data có trách nhiệm cung cấp dữ liệu được yêu cầu bởi ứng dụng. Tầng data phải được thiết kế sao cho dữ liệu có thể được sử dụng lại ở bất kì ứng dụng nào mà không cần sửa đổi logic của tầng Presentation.
Package api cung cấp các network interface.
Package db cung cấp các local database interface.
Package repository nhiệm vụ implement dữ liệu từ local, remote.
class NewsRepositoryImpl(private val remote: NewsRemoteImpl,
private val cache: NewsCacheImpl) : NewsRepository {
override fun getLocalNews(): Flowable<NewsSourcesEntity> {
return cache.getNews()
}
override fun getRemoteNews(): Flowable<NewsSourcesEntity> {
return remote.getNews()
}
override fun getNews(): Flowable<NewsSourcesEntity> {
val updateNewsFlowable = remote.getNews()
return cache.getNews()
.mergeWith(updateNewsFlowable.doOnNext{
remoteNews -> cache.saveArticles(remoteNews)
})
}
}
Repositories hoạt động như 1 điểm truy cập duy nhất tới data layer.
What is the Presentation layer?
Presentation layer cung cấp giao diện người dùng của ứng dụng.
Đây là layer "câm" chỉ thực hiện lệnh mà không bao gồm logic trong đó, kết nối mọi thứ với nhau.
Presentation có thể triển khai theo các pattern khác nhau như MVC, MVP, MVVM, MVI...
How all the layers are connected?
Sau khi đã hiểu nhiệm vụ của các layer, giờ thì mình sẽ ghép nối lại xem các layer connect với nhau như nào nhé.
- Mỗi layer có các entities riêng được xác định riêng.
- Mapper được sử dụng để chuyển đổi các entities từ layer này qua layer khác.
- Việc xây dựng các entities riêng biệt cho các layer giúp nó trở nên hoàn toàn độc lập và chỉ có dữ liệu cần thiết mới chuyển sang layer tiếp theo.
Conclusion
Hi vọng qua bài viết các bạn có thể hiểu được cơ bản về clean architecture cũng như flow của nó.
Mọi người có thể xem qua sample tại đây. Happy coding !!!
References






