美文网首页
Google官方MVP项目(一)

Google官方MVP项目(一)

作者: 奋斗的Leo | 来源:发表于2016-05-10 22:18 被阅读241次

项目地址:https://github.com/googlesamples/android-architecture/tree/todo-mvp
最基础的MVP项目,是一个类似备忘录的项目。项目目录结构如下图:

QQ图片20160510214004.png
  • java目录下,基本是按照功能来划分,除了util是工具模块,data是Model模块。
  • test目录下,是测试模块,由于是MVP模式,所以只需要对Presenter模块测试就行
    不同功能的代码类似,所以可以简单看下添加备忘录功能实现模块,类比其他功能模块。

这是添加功能模块目录结构,如下:


QQ截图20160510214746.png
  • Fragment是View模块,只负责UI上的功能,持有Persener对象的引用
  • Presenter负责逻辑代码,不涉及任何UI上的具体操作,持有View对象的引用
  • Contract定义了Viwe模块和Presenter模块各自的实现接口
  • Activity负责架起View模块和Presenter模块的桥梁

接下来,我们来看下具体代码的实现,先看AddEditTaskContract类的定义:
<pre>
<code>
public interface AddEditTaskContract
{

interface View extends BaseView<Presenter>
{
    void showEmptyTaskError();

    void showTasksList();

    void setTitle(String title);

    void setDescription(String description);

    boolean isActive();
}

interface Presenter extends BasePresenter
{
    void createTask(String title, String description);

    void updateTask(String title, String description);

    void populateTask();
}

}
</code>
</pre>
该类分为两个部分,分别定义了View模块需要实现的接口和Persenter模块实现的接口。
再看下AddEditTaskActivity类的主要代码:
<pre>
<code>
AddEditTaskFragment addEditTaskFragment = (AddEditTaskFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame);

    String taskId = null;
    if (addEditTaskFragment == null)
    {
        addEditTaskFragment = AddEditTaskFragment.newInstance();

        if (getIntent().hasExtra(AddEditTaskFragment.ARGUMENT_EDIT_TASK_ID))
        {
            taskId = getIntent().getStringExtra(
                    AddEditTaskFragment.ARGUMENT_EDIT_TASK_ID);
            actionBar.setTitle(R.string.edit_task);
            Bundle bundle = new Bundle();
            bundle.putString(AddEditTaskFragment.ARGUMENT_EDIT_TASK_ID, taskId);
            addEditTaskFragment.setArguments(bundle);
        } else
        {
            actionBar.setTitle(R.string.add_task);
        }

        ActivityUtils.addFragmentToActivity(getSupportFragmentManager(),
                addEditTaskFragment, R.id.contentFrame);
    }

    // Create the presenter
    new AddEditTaskPresenter(
            taskId,
            Injection.provideTasksRepository(getApplicationContext()),
            addEditTaskFragment);

</code>
</pre>
和AddEditTaskPresenter类的构造方法:
<pre>
<code>
public AddEditTaskPresenter(@Nullable String taskId, @NonNull TasksDataSource tasksRepository, @NonNull AddEditTaskContract.View addTaskView
{

 mTaskId = taskId;
    
mTasksRepository = checkNotNull(tasksRepository);
    
mAddTaskView = checkNotNull(addTaskView);

 mAddTaskView.setPresenter(this);
}

</code>
</pre>
综合两部分代码来看,可以知道

  • Actvity中实例化AddEditTaskFragment,并通过调用AddEditTaskPresenter构造方法,将Fragment传递给Presenter

  • AddEditTaskPresenter中又通过setPresenter将本身赋值给AddEditTaskFragment
    这样AddEditTaskFragment和AddEditTaskPresenter各自拥有对方实例的引用
    下面是新建新的备忘录代码:
    <pre>
    <code>
    mPresenter.createTask(

    mTitle.getText().toString(),

    mDescription.getText().toString());
    </code>
    </pre>
    <pre>
    <code>
    @Override
    public void createTask(String title, String description)
    {
    Task newTask = new Task(title, description);
    if (newTask.isEmpty())
    {
    mAddTaskView.showEmptyTaskError();
    } else
    {
    mTasksRepository.saveTask(newTask);
    mAddTaskView.showTasksList();
    }
    }
    </code>
    </pre>
    当点击新建按钮,Fragment就调用Presenter的createTask,让Persenter来实现具体的代码,而在Perseter中当逻辑代码执行完毕时,由通过调用Fragment的showEmptyTaskError或showTasksList来更新UI,通知用户操作结果。这样子,就将代码逻辑和界面更新两个操作完全分离开来。

接下来,我们来看下Test测试代码,就知道上面这样做的好处了:
<pre>
<code>
@Test
public void saveNewTaskToRepository_showsSuccessMessageUi()
{

    // Get a reference to the class under test
    mAddEditTaskPresenter = new AddEditTaskPresenter("1", mTasksRepository, mAddEditTaskView);

    // When the presenter is asked to save a task
    mAddEditTaskPresenter.createTask("New Task Title", "Some Task Description");

    // Then a task is saved in the repository and the view updated
    verify(mTasksRepository).saveTask(any(Task.class)); // saved to the model
    verify(mAddEditTaskView).showTasksList(); // shown in the UI
}

</code>
</pre>
这里我们只看主要代码,先实例化一个Presenter对象,调用createTask来模拟新增新的备忘录,通过verify来检查saveTask和showTasksList两个方法是否被调用。


小结一下:MVP模式,对android代码来说是个很好的设计模式,将界面UI操作和逻辑代码实现完全分离开来,不管是写单元测试代码,还是后期功能改动都是比较方便的

相关文章

网友评论

      本文标题:Google官方MVP项目(一)

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