首先,不了解 Clean 架构的可以看看这个,不过也没关系,阅读本文后你也许会对Clean架构思想有一个认识。

对比MVP项目的结构图,我们发现不同之处是新增的这个Domain Layer这层,来隔离Presentation Layer和Data Layer,负责了所有的业务逻辑交互,那么本文就主要来分析这层的设计和实现。

 
MVP-Clean架构图

我们仍然以Sample中详情界面(功能)来进行分析,下图展示了在 TaskDetailFragment 中点击删除按钮,然后所经历的逻辑交互以及最后完成了界面更新。

 
时序图

1、在 TaskDetailFragment 中点击菜单,调用 Presenter 的 deleteTask() 方法:

    @Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_delete:
mPresenter.deleteTask();
return true;
}
return false;
}

2、Presenter 的 deleteTask() 方法,是使用UseCaseHandler类中的 UseCaseScheduler 对象来执行任务,并处理结果和异常。

    // TaskDetailPresenter 中deleteTask() 方法
@Override
public void deleteTask() {
mUseCaseHandler.execute(mDeleteTask, new DeleteTask.RequestValues(mTaskId),
new UseCase.UseCaseCallback<DeleteTask.ResponseValue>() {
@Override
public void onSuccess(DeleteTask.ResponseValue response) {
mTaskDetailView.showTaskDeleted();
} @Override
public void onError(Error error) {
// Show error, log, etc.
}
});
} // UseCaseHandler 中 execute() 方法
public <T extends UseCase.RequestValues, R extends UseCase.ResponseValue> void execute(
final UseCase<T, R> useCase, T values, UseCase.UseCaseCallback<R> callback) {
useCase.setRequestValues(values);
useCase.setUseCaseCallback(new UiCallbackWrapper(callback, this)); // The network request might be handled in a different thread so make sure
// Espresso knows
// that the app is busy until the response is handled.
EspressoIdlingResource.increment(); // App is busy until further notice mUseCaseScheduler.execute(new Runnable() {
@Override
public void run() {
useCase.run();
// This callback may be called twice, once for the cache and once for loading
// the data from the server API, so we check before decrementing, otherwise
// it throws "Counter has been corrupted!" exception.
if (!EspressoIdlingResource.getIdlingResource().isIdleNow()) {
EspressoIdlingResource.decrement(); // Set app as idle.
}
}
});
}

3、UseCaseHandler 类中维护了 UseCaseThreadPoolScheduler 的示例对象,在其中定义了 ThreadPoolExecutor 来执行异步任务,任务的结果回调则使用 Handler post的方式来切换到主线程。

    // UseCaseHandler 中初始化 UseCaseThreadPoolScheduler 对象
public static UseCaseHandler getInstance() {
if (INSTANCE == null) {
INSTANCE = new UseCaseHandler(new UseCaseThreadPoolScheduler());
}
return INSTANCE;
} // UseCaseThreadPoolScheduler 中定义了 ThreadPoolExecutor 对象
public UseCaseThreadPoolScheduler() {
mThreadPoolExecutor = new ThreadPoolExecutor(POOL_SIZE, MAX_POOL_SIZE, TIMEOUT,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(POOL_SIZE));
} // 并执行异步任务
@Override
public void execute(Runnable runnable) {
mThreadPoolExecutor.execute(runnable);
} // response使用Handler来处理结果回调
@Override
public <V extends UseCase.ResponseValue> void notifyResponse(final V response,
final UseCase.UseCaseCallback<V> useCaseCallback) {
mHandler.post(new Runnable() {
@Override
public void run() {
useCaseCallback.onSuccess(response);
}
});
}

4、UseCaseHandler 中其实还是调用 UseCase 的 run() 方法,而 UseCase 的 executeUseCase() 是抽象方法,最终逻辑是由各个Task子类实现的,比如 DeleteTask:

    @Override
protected void executeUseCase(final RequestValues values) {
mTasksRepository.deleteTask(values.getTaskId());
getUseCaseCallback().onSuccess(new ResponseValue());
}

从以上的分析流程中可以看出,原本位于 Presenter 中的业务逻辑转移到了 UseCaseHandler 中,UseCaseHandler 使用 UseCaseScheduler 来切换工作线程和UI线程,使用 UseCase 来处理每个 Task 的逻辑。其类图如下:

 
UML类图

** 总结 **

  • 与MVP最大的不同是加入了 Domain layer 和 use cases,把原本位于 Presenter 中臃肿的逻辑代码移到了 Domain layer 中,减轻了 Presenter 的体量,而 use cases 定义了每个业务的具体操作,细化了业务粒度,也有效提高了代码的重用性。
  • 使用 UseCaseScheduler 来提供线程池执行异步任务,并可以切换工作线程和UI线程。

转载请标明出处:http://www.jianshu.com/p/7ae3095f2cb5

作者:spiritTalk
链接:https://www.jianshu.com/p/7ae3095f2cb5
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

【转】Android官方架构项目之MVP + Clean的更多相关文章

  1. 改造 Android 官方架构组件 ViewModel

    前言 Android 官方架构组件在今年 5 月份 Google I/O 大会上被公布, 直到 11 月份一直都是测试版, 由于工作比较繁忙, 期间我只是看过类似的文章, 但没有在实际项目中使用过, ...

  2. Android官方架构组件介绍之LifeCycle(一)

    Android官方架构组件介绍之LifeCycle 下面是官方提供的Android App开发的架构图: 从上图可以看到一些关键字:ViewModel,LiveData,Room等.其实看了上面视频的 ...

  3. Android官方架构组件指南

    此指南适用于那些曾经或现在进行Android应用的基础开发,并希望了解和学习编写Android程序的最佳实践和架构.通过学习来构建强大的生产级别的应用. 注意:此指南默认你对Android开发有比较深 ...

  4. Android官方架构组件介绍之LifeCycle

    Google 2017 I/O开发者大会于近日召开,在开发者大会上谷歌除了发布了Android O等一些新产品之外,也对Android代码的架构做出了一个官方的回应. Google 2017 I/O开 ...

  5. Android官方架构组件介绍之ViewModel

    ViewModel 像Activity,Fragment这类应用组件都有自己的生命周期并且是被Android的Framework所管理的.Framework可能会根据用户的一些操作和设备的状态对Act ...

  6. Android官方架构组件介绍之ViewModel(三)

    ViewModel 像Activity,Fragment这类应用组件都有自己的生命周期并且是被Android的Framework所管理的.Framework可能会根据用户的一些操作和设备的状态对Act ...

  7. Android官方架构组件介绍之应用(四)

    讲一个项目常见的功能,友盟统计功能 例如一个项目有很多多modlue,每个里面modlue都有Activity,Activity需要友盟统一,Fragment也需要友盟统计.一般做法就是继承一个Bas ...

  8. Android官方架构组件介绍之LiveData

    LiveData LiveData是一个用于持有数据并支持数据可被监听(观察).和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle ...

  9. Android官方架构组件介绍之LiveData(二)

    LiveData LiveData是一个用于持有数据并支持数据可被监听(观察).和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle ...

随机推荐

  1. redis12-----redis 与关系型数据库的对比

    书和书签系统 create table book ( bookid int, title ) )engine myisam charset utf8; insert into book values ...

  2. Java 8 新的时间日期 API

    1. 概述 1.1 简介 Java 8 引入了一套全新的时间日期API,操作起来更简便.简单介绍下,LocalDate和LocalTime和LocalDateTime的使用: java.util.Da ...

  3. Linux 高精度定时器hrtimer 使用示例【转】

    本文转载自:http://blog.csdn.net/dean_gdp/article/details/25481225 hrtimer的基本操作 Linux的传统定时器通过时间轮算法实现(timer ...

  4. YTU 2209: 建立链表(线性表)

    2209: 建立链表(线性表) 时间限制: 1 Sec  内存限制: 128 MB 提交: 282  解决: 185 题目描述 (线性表)设键盘输入n个英语单词,输入格式为n, w1, w2, -,w ...

  5. String bulit-in function

    tip: 和tuple一样,字符串也是不可变的类型,字符串的内建函数有非常多,我们一一举例来看看他们的作用 下面是用dir(str) 输出的内容: ['__add__', '__class__', ' ...

  6. Oracle:ORA-09925 and linux Read-only file system error

    今天上午有同事反映应用数据库连接不上:于是排查数据库: [oracle@db ~]$ sqlplus / as sysdba SQL*Plus: Release - Production on Thu ...

  7. SPOJ:String Play (?)

    String Play Milo has a string S of length L. Tutu picks a random prefix and Mota picks a random suff ...

  8. 【JSOI 2014】序列维护

    [题目链接] 点击打开链接 [算法] 线段树 注意标记下传 [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 5 ...

  9. bzoj2676

    二分概率+矩乘+dp 也是二分概率,然后dp[i][j][k]表示当前到了i,有j条命,下一次的收益是k,然后矩乘转移,但是我自己的似乎wa了,抄了liu_runda的才行,具体不知道为什么 注释的是 ...

  10. View Controller Programming Guide for iOS---(三)---Using View Controllers in Your App

    Using View Controllers in Your App Whether you are working with view controllers provided by iOS, or ...