[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 ?

  1. 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.
  2. Tăng tính trừu tượng
  3. Tránh ràng buộc
  4. Dễ dàng kiểm thử

Layers ?

alt text

  • 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. alt text

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.

alt text

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?

alt text

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.

alt text

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

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

Hades

11 bài viết.
16 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
9 13
Dưới đây là một cách tổ chức thư mục mà mình cho là khá hợp lý. Hi vọng mọi người có thể tham khảo và góp ý :smile: Android_structure ├─ com.abc ...
Hades viết hơn 3 năm trước
9 13
Male avatar
5 2
Những điều cần nhớ Hades 22042017 Đừng dùng lại Đừng sử dụng lại strings cho nhiều màn hình khác nhau. 1. Tưởng tượng rằng bạn có một hộp thoạ...
Hades viết gần 3 năm trước
5 2
Male avatar
4 0
Giới thiệu RecycleView là một viewGroup mới được giới thiệu trong Android L ( API 21 ). Đây là một viewGroup có chức năng tương tự như ListView nh...
Hades viết hơn 3 năm trước
4 0
Bài viết liên quan
White
13 4
(Ảnh) Query filter là một vấn đề khá quen thuộc cho dù bạn code ngôn ngữ hay nền tảng nào. Các form search dữ liệu nâng cao với field, column cần f...
Reishou viết 11 tháng trước
13 4
White
42 7
(Ảnh) _Bài viết tham khảo nội dung và hình ảnh từ hai cuốn sách gối đầu giường của dev, (Link) và (Link), nếu có thời gian thì các bạn có thể tìm ...
Nguyễn Anh Tuấn viết gần 3 năm trước
42 7
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
11 bài viết.
16 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!