手把手寫一個Clean(+mvp+rxjava)架構的Demo

做者:點先生 時間:2018.12.26

前言

前段時間在天星羣中有朋友說到了clean架構。恰好在最近的項目裏面我在搭建框架的時候用到了clean,因此在這裏就把搭建過程在這裏描述一下。Demo在文章末尾。本文側重於clean的搭建,mvp+rxjava的部分,不作介紹。
(咦?我聽到有人在問什麼是天星羣。既然你誠心誠意的發問了,那我就給大家透露一下。天星是一羣Android開發者閒的沒事幹搞的一個博客團隊,這是團隊博客地址:點這裏,這個是粉絲qq羣:557247785。歡迎妹子和女裝大佬們!)html

CleanArchitecture

mvp和rxjava基本是如今開發標配,有不少寫的比較好的文章。對mvp和rxjava比較熟的同窗能夠繼續往下看了。還不熟的同窗能夠看看MVPRxjava1Rxjava2java

Clean是一種架構的思想,跟MVP同樣,解耦就完事兒了。(那一羣解耦狂魔,你根本不知道他們究竟想怎樣!)關於clean框架的解析不少,我再也不贅述,畢竟本文是手把手寫一個Demo。react

Clean思想由Uncle Bob提出的,英文不錯的看這個 The Clean Code Blog
Google爸爸寫的Demo能夠做爲參考todo‑mvp‑clean
android10的文章圖解多,比較容易理解,推薦!Android-CleanArchitecture
中文版能夠看看來自谷歌清潔工Clean架構探討,我以爲講的很好。android

按慣例這裏該有一張表情包,可是我沒有找到能夠皮的理由,因此,算了。git

手把手寫mvp+rxjava+clean

如今來模擬一個登錄功能。mvp是clean架構的基礎,咱們先把mvp+rxjava的框架給弄好。個人項目結構是這樣的。 github

項目結構

分爲了data,domain,presentation 三層。分別對應clean的三層。 data層和presentation層你們應該都比較熟悉,就是一些mvp的東西。 那這個domain layout是幹嗎的?bash

業務邏輯,use case實現的地方 之前在mvp架構的時候,咱們會說。我要是不知道這個app能幹嗎,看一眼presenter的接口就知道了。那在clean裏面就能夠說。我要是不知道這app能幹嗎,看一眼domain層就知道了。
usecase更加簡化了presenter裏面的代碼 之前presenter裏面會調用data層的東西,如今presenter只管負責的usecase。代碼量大大的減小。
usecase純java代碼,不含androd依賴架構

那usecase是幹嗎的? 看看google官方todo‑mvp‑clean裏面Usecase在幹嗎,又是如何調用的。app

Google clean demo核心解析

UseCase

  1. 抽象類
  2. 傳進來了請求參數Q,響應參數P
  3. 有一個回調接口UseCaseCallback
  4. set幾個屬性的方法。
  5. run(): 帶着Q執行usecase

UseCase實現類

  1. 構造函數傳入了repository
  2. P,Q兩個靜態內部類
  3. executeUseCase():經過傳入的repository執行數據請求的操做,並執行回調函數。

UseCaseHandler

  1. 統一管理Usecase的execute方法。
  2. 經過execute方法把須要處理的UseCase<T, R>、請求參數T、回調接口UseCase.UseCaseCallback進行綁定,方便請求與回調。

presenter裏的使用

使用哪一個方法的時候,就調用傳入哪一個usecase,和請求須要的參數,和相應的回調接口。框架

咱們繼續手把手

UseCaseHandler主要做用就是統一管理,回調直觀。 當咱們把rxjava2加入進來以後,UseCaseHandler就沒有存在的意義了。 去掉handler,不須要綁定這雜七雜八的東西以後,usecase能夠簡化了。因此個人BaseUseCase是這樣的

MyUseCase

public abstract class BaseUseCase<P, Q> {
    private final Scheduler observerThread;
    private final Scheduler subcriberThread;
    private final CompositeDisposable disposables;

    public BaseUseCase(Scheduler observerThread, Scheduler subcriberThread) {
        this.observerThread = observerThread;
        this.subcriberThread = subcriberThread;
        this.disposables = new CompositeDisposable();
    }

    protected abstract Observable<Q> buildUseCaseObservable(P request);

    public void execute(DisposableObserver<Q> observer, P request) {
        Preconditions.checkNotNull(observer);
        final Observable<Q> observable = this.buildUseCaseObservable(request)
                .subscribeOn(observerThread)
                .observeOn(subcriberThread);
        addDisposable(observable.subscribeWith(observer));
    }

    public void dispose() {
        if (!disposables.isDisposed()) {
            disposables.dispose();
        }
    }

    public void addDisposable(Disposable disposable) {
        Preconditions.checkNotNull(disposable);
        Preconditions.checkNotNull(disposables);
        disposables.add(disposable);
    }
}
複製代碼

跟google的demo作了同樣的事,不過加了CompositeDisposable統一管理而已。

MyUseCase實現類

public class LoginUseCase extends BaseUseCase<LoginUseCase.RequestValue, User> {

    private final Repository repository;

    public LoginUseCase(Scheduler observerThread, Scheduler subcriberThread, Repository repository) {
        super(observerThread, subcriberThread);
        this.repository = repository;
    }

    @Override
    protected Observable<User> buildUseCaseObservable(RequestValue request) {
        return repository.getUser(request.account, request.password);
    }

    public static final class RequestValue {
        final String account;
        final String password;

        public RequestValue(String account, String password) {
            this.account = Preconditions.checkNotNull(account);
            this.password = Preconditions.checkNotNull(password);
        }
    }
}
複製代碼

跟google的demo差很少基本一致,把ResponseValue改爲了返回的實體類。

MyPresenter裏的使用

@Override
    public void login(String account, String password) {
        loginUseCase.execute(new LoginObserver(), new LoginUseCase.RequestValue(account, password));
    }

    private final class LoginObserver extends DisposableObserver<User> {
        @Override
        public void onNext(User user) {  loginUseCase.saveUser(user); }

        @Override
        public void onError(Throwable e) {  }

        @Override
        public void onComplete() {  }
    }
複製代碼

其餘

/*ButterKnife*/
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    /*GreenDao*/
    implementation 'org.greenrobot:greendao:3.2.2'
    /*Retrofit*/
    implementation 'com.squareup.retrofit2:retrofit:2.0.2'
    implementation 'com.squareup.okhttp3:okhttp:3.1.2'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    implementation 'com.squareup.okhttp3:okhttp-urlconnection:3.5.0'
    /*Rxjava2*/
    implementation 'io.reactivex.rxjava2:rxjava:2.1.3'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
複製代碼

所有源碼在這裏:github.com/GuitarDian/…

相關文章
相關標籤/搜索