美文网首页Android 干货精粹
Android官方架构分析(二)——todo‑mvp‑clean

Android官方架构分析(二)——todo‑mvp‑clean

作者: 管弦_ | 来源:发表于2017-08-11 20:02 被阅读0次

    前言

    这篇文章将对android-architecture项目中的todo‑mvp‑clean设计模式进行分析。

    由于todo‑mvp‑clean项目是在todo‑mvp项目的基础上扩展出来的,所以在读这篇文章之前最好有了解过todo‑mvp的代码,并且读过上一篇文章android-architecture源码分析(一)——todo‑mvp

    架构思路

    todo-mvp-clean架构模式是基于标准MVP架构和Clean Architecture的概念相结合来设计实现的。

    image

    上图可以看到,addedittask包下面多了domain.usecase包,下面的3个类DeleteTask、GetTask、SaveTask分别封装了删除、获取和保存3个业务逻辑代码。以GetTask为例进行分析:

    /**
     * Retrieves a {@link Task} from the {@link TasksRepository}.
     */
    public class GetTask extends UseCase<GetTask.RequestValues, GetTask.ResponseValue> {
    
        private final TasksRepository mTasksRepository;
    
        public GetTask(@NonNull TasksRepository tasksRepository) {
            mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null!");
        }
    
        @Override
        protected void executeUseCase(final RequestValues values) {
            mTasksRepository.getTask(values.getTaskId(), new TasksDataSource.GetTaskCallback() {
                @Override
                public void onTaskLoaded(Task task) {
                    if (task != null) {
                        ResponseValue responseValue = new ResponseValue(task);
                        getUseCaseCallback().onSuccess(responseValue);
                    } else {
                        getUseCaseCallback().onError();
                    }
                }
    
                @Override
                public void onDataNotAvailable() {
                    getUseCaseCallback().onError();
                }
            });
        }
    
        public static final class RequestValues implements UseCase.RequestValues {
    
            private final String mTaskId;
    
            public RequestValues(@NonNull String taskId) {
                mTaskId = checkNotNull(taskId, "taskId cannot be null!");
            }
    
            public String getTaskId() {
                return mTaskId;
            }
        }
    
        public static final class ResponseValue implements UseCase.ResponseValue {
    
            private Task mTask;
    
            public ResponseValue(@NonNull Task task) {
                mTask = checkNotNull(task, "task cannot be null!");
            }
    
            public Task getTask() {
                return mTask;
            }
        }
    }
    
    

    GetTask继承了UseCase类重写了executeUseCase方法,在executeUseCase方法中直接使用TasksRepository对象调用getTask方法来获取数据,这也证明了UseCase是对业务逻辑的抽象这一说法。而RequestValues和ResponseValue分别实现了UseCase.RequestValues和UseCase.ResponseValue接口,分别作为请求参数和返回参数。

    /**
     * Listens to user actions from the UI ({@link AddEditTaskFragment}), retrieves the data and
     * updates
     * the UI as required.
     */
    public class AddEditTaskPresenter implements AddEditTaskContract.Presenter {
    
        private final AddEditTaskContract.View mAddTaskView;
    
        private final GetTask mGetTask;
    
        private final SaveTask mSaveTask;
    
        private final UseCaseHandler mUseCaseHandler;
    
        @Nullable
        private String mTaskId;
    
        /**
         * Creates a presenter for the add/edit view.
         *
         * @param taskId      ID of the task to edit or null for a new task
         * @param addTaskView the add/edit view
         */
        public AddEditTaskPresenter(@NonNull UseCaseHandler useCaseHandler, @Nullable String taskId,
                @NonNull AddEditTaskContract.View addTaskView, @NonNull GetTask getTask,
                @NonNull SaveTask saveTask) {
            mUseCaseHandler = checkNotNull(useCaseHandler, "useCaseHandler cannot be null!");
            mTaskId = taskId;
            mAddTaskView = checkNotNull(addTaskView, "addTaskView cannot be null!");
            mGetTask = checkNotNull(getTask, "getTask cannot be null!");
            mSaveTask = checkNotNull(saveTask, "saveTask cannot be null!");
    
            mAddTaskView.setPresenter(this);
        }
    
        @Override
        public void start() {
            if (mTaskId != null) {
                populateTask();
            }
        }
        
        ...
        
        
        @Override
        public void populateTask() {
            if (mTaskId == null) {
                throw new RuntimeException("populateTask() was called but task is new.");
            }
    
            mUseCaseHandler.execute(mGetTask, new GetTask.RequestValues(mTaskId),
                    new UseCase.UseCaseCallback<GetTask.ResponseValue>() {
                        @Override
                        public void onSuccess(GetTask.ResponseValue response) {
                            showTask(response.getTask());
                        }
    
                        @Override
                        public void onError() {
                            showEmptyTaskError();
                        }
                    });
        }
        
        ...
        
    }
    

    AddEditTaskPresenter类中的构造函数,直接获取了UseCaseHandler实例、taskId参数、View实例、GetTask实例、SaveTask实例,mUseCaseHandler直接执行execute方法,参数分别是GetTask实例、RequestValues请求参数对象、UseCaseCallback回调接口。

    至此,一套完整的调用逻辑流程已经清晰:

    • Presenter实例调用逻辑方法。
    • UseCaseHandler对象启动子线程执行UseCase实例。
    • UseCase实例执行executeUseCase方法,调用Data层实例对象执行数据操作。
    • Data层实例对象完成数据操作以后执行UseCase实例中UseCaseCallback回调接口方法。
    • 在主线程中执行UseCaseCallback的回调方法,渲染View层显示数据。

    总结

    Clean Architecture最大特点是引入了Domain层,使得Presenter层和Model层进一步解耦;而UseCase则增强了业务逻辑代码的复用性和可读性,从而维护起来更为简单方便。

    相关文章

      网友评论

        本文标题:Android官方架构分析(二)——todo‑mvp‑clean

        本文链接:https://www.haomeiwen.com/subject/muvrrxtx.html