获取微信精选文章,可以定义为一个业务。
在 presentation 层,点击了 Button 按钮,向 Presenter 层,发出获取文章指令 getArticleList()
,
Presenter 层收到指令,调用 UseCase.execute()
,这时就与 domain 层产生联系了。
在 execute 方法中,通过 Repository 接口从 data 层获取数据。
获取数据后,再通过回调,最终 presentation 层拿到数据,进行文章列表展示。
代码实现
创建 ArticleView
public interface ArticleView extends IView {
void getArticleSuccess(List articleBeanList);
void getArticleFail(String failMsg);
}
创建 ArticlePresenter
public class ArticlePresenter extends BasePresenter {
public void getArticleList(String key) {
}
}
上面我们说过,Presenter
层是由一个或多个 UseCase
组成,
他们的主要任务是执行异步任务,获取数据。那么我们在 domain
层定义一个 UseCase
,
名为 ArticleCase
,详细代码如下:
public class ArticleCase extends UseCase<List, String> {
private ArticleRepository articleRepository;
public ArticleCase(ArticleRepository repository) {
this.articleRepository= repository;
}
@Override
protected Observable<List> buildObservable(String s) {
return articleRepository.getArticleList(s);
}
}
UseCase 是封装好的一个 Case 基类:
/**
- Case 基类
- @param 返回数据
- @param 请求参数
*/
public abstract class UseCase<T, Params> {
private final CompositeDisposable mDisposables;
public UseCase() {
this.mDisposables = new CompositeDisposable();
}
@SuppressLint(“CheckResult”)
public void execute(Params params, Consumer nextConsumer, Consumer errorConsumer) {
Observable observable = this.buildObservable(params);
addDisposable(observable.subscribe(nextConsumer, errorConsumer));
}
protected abstract Observable buildObservable(Params params);
private void addDisposable(Disposable disposable) {
mDisposables.add(disposable);
}
@SuppressLint(“CheckResult”)
public void execute(Params params, BaseObserver observer) {
Observable observable = this.buildObservable(params);
observable.subscribe(observer);
addDisposable(observer.getDisposable());
}
public void dispose() {
if (!mDisposables.isDisposed()) {
mDisposables.dispose();
}
}
}
任何一个业务类,都需要去继承 UseCase
,并实现 buildObservable
方法。
继续看 ArticleCase
,我们用到了接口 ArticleRepository
,很明显,
这个接口用于被 data 层实现,从而获取数据并回调。
public interface ArticleRepository {
Observable<List> getArticleList(String param);
}
接下来在 data 层,去实现 ArticleRepository
:
public class ArticleRepositoryImpl implements ArticleRepository {
private DataApi mApi;
public ArticleRepositoryImpl() {
mApi = JDHttp.createApi(DataApi.class);
}
@Override
public Observable<List> getArticleList(String param) {
return mApi.getArticleList(param).compose(JDTransformer.switchSchedulers())
.map(new Function<BaseResponse, List>() {
@Override
public List apply(BaseResponse baseResponse) throws Exception {
return baseResponse.getResult().getList();
}
});
}
}
在这里,进行了获取数据操作。无论是从网络、还是本地获取,domain
层不需要知道。
然后在 Presenter
层中实现 ArticleCase
,并调用 execute()
方法,获取数据。
public class ArticlePresenter extends BasePresenter {
private ArticleCase mCase;
public void getData(String key) {
mCase.execute(key, new BaseObserver<List>() {
@Override
public void onSuccess(List articleBeanList) {
getView().getArticleSuccess(articleBeanList);
}
@Override
public void onFail(String failMsg) {
getView().getArticleFail(failMsg);
}
});
}
@Override
public List createCases() {
mCase = new ArticleCase(new ArticleRepositoryImpl());
mCaseList.add(mCase);
return mCaseList;
}
}
并且在 BasePresenter
中实现自动取消订阅:
public abstract class BasePresenter implements IPresenter {
private V mView;
private CPBridge mBridge = new CPBridge();
protected List mCaseList = new ArrayList<>();
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void attach(V view) {
this.mView = view;
createCases();
mCaseList.forEach(new Consumer() {
@Override
public void accept(UseCase useCase) {
mBridge.addCase(useCase);
}
});
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void detach() {
this.mView = null;
mBridge.removeCase();
}
protected abstract List createCases();
public V getView() {
if (isViewAttached()) {
return mView;
} else {
throw new IllegalStateException(“Please call IPresenter.attach(IView view) before requesting data”);
}
}
private boolean isViewAttached() {
return null != mView;
}
}
感觉绕吗?没关系,结合简单的业务,将代码反复的敲几次,你就明白了,相信我。
具体代码实现请看 demo。
总结
通过上面的代码,实现一个业务,虽然写了好多类,好多代码。
但是这样写的好处也是显而易见的:整体架构更加清晰、易维护、方便测试、高内聚、低耦合。
同时也希望阅读过这篇文章的人,可以亲手实践。通过实践,你会明白很多之前不明白的问题。
希望这篇文章能对你有用,谢谢。
最后,附上 demo 地址:MVP-Clean-Demo
您的 star 是我前进的动力,欢迎 star!
最后
小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取
成体系的自学效果低效漫长且无助**。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-AQfGPhjw-1719102816025)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取