安卓Android架构

Android MVP从懵逼到入门:登陆业务实践

2016-07-13  本文已影响6176人  星际之痕

MVP简介

最近几天在啃MVP,现在的你或许跟几天前的我一样,对MVP还是一脸懵逼,虽然MVP三个字母都认识,但连在一起却不明白到底是个什么东东,没关系,快来干了这碗鸡汤,立马从懵逼到入门,入不了门你来打我,文末统计人数。


首先,MVP是一种设计模式,或者说架构。Google把它列入Android Architecture Blueprints--Android 架构蓝图,并给出了官方的例子来解释如何实现MVP。本文实现的登陆功能就是根据MVP基础架构Demo来实现的。

其次,MVP从何而来?想必都知道是MVC的演化版本,现在比较流行,被广大开发者所认可。被认可的原因我在这里总结一下:

一直以来,在MVC模式中Activity的万能角色就备受诟病,一旦逻辑越来越复杂,Activity就越来越臃肿,承担越来越多的职责,代码阅读起来费劲,维护成本跟着提高,而且,在MVC模式中,View 和 Model直接交互,耦合度高,违背了软件开发“高类聚、低耦合”的设计目标--于是MVP横空出世。

关于MVP的理论知识就哔哔这些,想要详细了解的童鞋回头自己做功课去,这里不是重点,本文的重点是把MVP模式实践起来。

MVP实现登陆

mvp.png

这是google samples TODO-MVP项目中的MVP图解。因为本人学习MVP主要也是根据谷歌官方demo来的,所以,这个图直接拿来。这个图怎么看?


[图片上传失败...(image-17e711-1521790364530)]

[图片上传失败...(image-220445-1521790364530)]
[图片上传失败...(image-edaa6-1521790364530)]

这其实是MVP的一个关键点,通过这个接口,View的实现类(即Fragment)就持有了Presenter的实例,于是,View就可以通过Presenter来操作Model中的数据接口了。如果你要实现MVP模式,记住,不管三七二十一,先写这个基佬,哦,不对,是基类。

Presenter接口基类里同样定义了一个接口:

  void start();

这个方法就是直接操作Model的,比如加载数据。通过这两个基类的定义的接口就能看出,View和Model不直接交互,而是通过Presenter来操作,这是与MVC的不同之处。

为其赋值。

注意官方的demo说明里有这段内容:

Note: in a MVP context, the term "view" is overloaded:

The class android.view.View will be referred to as "Android View"
The view that receives commands from a presenter in MVP, will be simply called "view".

我来献个丑,翻译一下:

注意:在MVP的上下文里,“view”一词有多重含义:

  • android.view.View被称为“Android View”

什么意思?

我的理解是这样的:MVP中的VIEW由两部分组成,一个是view接口,比如上面的LoginContract.View接口;一个是该接口的实现类,比如上面的LoginFragment。view接口负责与presenter交互,presenter调用view接口定义方法来操作view的实现类;具体实现都是在android.view.View里实现的,即LoginFragment。

然后,你想让View干嘛,调用View相对应的接口就行了,想要什么数据,想对数据做什么操作,调用Model对象的对应方法就行了;或许你已经发现了:

Presenter对View的操作都是通过接口来完成的。

It uses fragments for two reasons:

The separation between Activity and Fragment fits nicely with this implementation of MVP: the Activity is the overall controller that creates and connects views and presenters.
Tablet layout or screens with multiple views take advantage of the Fragments framework.

献丑二进宫:

(MVP中的View实现)使用Fragment有两个原因:

Activity与Fragment之间的分离很好的符合了MVP的实现:Activity作为整体控制器来创建和连接views与presenters。
Tablet布局或者屏幕上有多个views的布局可以很好的利用Fragments框架。

在MVP模式里,Activity的功能变得简单了很多,一是创建View布局(Fragment),二是实例化Presenter(LoginPresenter),并将View(Fragment)作为参数,传入到Presenter(LoginPresenter)中,在Presenter(LoginPresenter)构造函数中传递给Presenter(LoginPresenter)持有的View对象,然后View对象调用setPresenter方法,将自身this传递给View实例(Fragment)。也就是上面说的“创建和连接views与presenters。

来看看Activity代码多简单:
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);

        LoginFragment loginFragment = (LoginFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame);        
        // Create the view        
        if (loginFragment == null) {            
            loginFragment = LoginFragment.newInstance("LOGIN_FRAGMENT");        
        }

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
        transaction.add(R.id.contentFrame, loginFragment);        
        transaction.commit(); 
   
        // Create the presenter        
        new LoginPresenter(
                getApplicationContext(),                
                UserRepository.getInstance(
                    UserLocalDataSource.getInstance(getApplicationContext()),
                    UserRemoteDataSource.getInstance()),                
                loginFragment);    
    }
  }

至此,MVP模式里的VP就可以运行起来了,连通起来了。下面来说说Model。如果对MVC的Model非常熟悉可以跳过。

MVP实践总结

使用MVP模式也有一些不尽如人意的地方,比如,类和接口变多了,代码也多了,项目大了可能会不好管理,但这都不是事,用多点代码、多点类文件换取低耦合度、结构清晰、容易理解、易扩展的架构,这买卖值了。

第一遍看的时候懵逼没关系,再看一遍,认真的解读MVP的设计思路,参考代码,发现其实真的是很清晰的思路,并不难,难的是啃下来的决心。这碗鸡汤我干了,你们随意。

相信看完这篇文章会对你理解MVP有所帮助,如果你还是一脸懵逼的话,请举起手来:
[图片上传失败...(image-e459b1-1521790364530)]

最后,奉上本文的源码GitHub:Login-MVP-Architecture,如果觉得有用,点个Star表示支持。

上一篇 下一篇

猜你喜欢

热点阅读