来自 金沙js77888 2020-03-02 00:29 的文章
当前位置: 金沙js77888 > 金沙js77888 > 正文

因为假如你不关心架构

为啥要关切架构划虚构计?因为只要你不关怀布局,那么有朝一日,要求在同一个特大的类中调护治疗若干错综相连的作业,你会发今后这么的标准下,根本不可能在此个类中飞速的找到以致有效的修改任何bug.当然,把这么的八个类想象为一个完好是辛勤的,由此,有希望部分重中之重的内幕总会在此个进度中会被忽视。

在这里,大家得以定义多个好的布局应该具备的特点:任务均衡分摊给全体名垂千古剧中人物的实体

可测验性常常都源于与上一条(对于贰个适用的结构是特别轻便)

易用性和低本钱维护

为何使用分布式?利用遍布式可以在咱们要弄通晓一些作业的原理时保持三个平衡的负荷。借使您以为你的花费职业愈来愈多,你的大脑越能习贯复杂的沉思,其实那是对的。可是,不能够忽略的三个实际是,这种思维技术并非线性拉长的,并且也并不可能异常的快的达到峰值。所以,能够征服这种复杂的最简易的方式正是在按照单一功能原则 的前提下,将效用划分给分化的实业。缘何必要易测性?其实这条供给对于怎么着习贯了单元测量检验的人并非一个主题材料,因为在增多了新的性格可能要追加部分类的纷纷之后日常会失效。那就象征,测验可避防止开拓者在运维时才开采标题----当应用达到客商的设施,每便维护都须求浪费长达最少二日的岁月本领重新分发给客户。缘何须求易用性?以此标题远非确定地点的答案,但值得说的是,最棒的代码是那么些未有写过的代码。由此,代码写的越少,Bug就越少。那意味着希望写越来越少的代码不该被单纯的解说为开荒者的懈怠,何况也不应该因为偏心更通晓的减轻方案而忽略了它的保养花费。MV体系概要现今大家已经有很构造划设想计情势方面包车型大巴选用:

MVC

MVP

MVVM

三种设计格局都把一个选拔中的实体分为以下三类:

视图:用户界面。控制器(Controller):业务逻辑模型:数据保存```**Models**--负责主要的数据或者操作数据的数据访问层,可以想象 Perspn 和 PersonDataProvider 类。**Views**--负责展示层,可以联想一下以 UI 开头的所有类。**Controller/Presenter/ViewModel**--负责协调 Model 和 View,通常根据用户在View上的动作在Model上作出对应的更改,同时将更改的信息返回到View上。将实体进行划分给我们带来了以下好处:1.更好的理解它们之间的关系2.复用(尤其是对于View和Model)3.独立的测试**一、MVC**MVC,Model View Controller,是软件架构中最常见的一种框架,简单来说就是通过controller的控制去操作model层的数据,并且返回给view层展示,具体见下图![Paste_Image.png](http://upload-images.jianshu.io/upload_images/5423625-309e4e5eb9cbec5f.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)当用户出发事件的时候,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上,这就是MVC的工作原理。那具体到Android上是怎么样一个情况呢?大家都知道一个Android工程有什么对吧,有Java的class文件,有res文件夹,里面是各种资源,还有类似manifest文件等等。对于原生的Android项目来说,layout.xml里面的xml文件就对应于MVC的view层,里面都是一些view的布局代码,而各种Java bean,还有一些类似repository类就对应于model层,至于controller层嘛,当然就是各种activity咯。大家可以试着套用我上面说的MVC的工作原理是理解。比如你的界面有一个按钮,按下这个按钮去网络上下载一个文件,这个按钮是view层的,是使用xml来写的,而那些和网络连接相关的代码写在其他类里,比如你可以写一个专门的networkHelper类,这个就是model层,那怎么连接这两层呢?是通过button.setOnClickListener()这个函数,这个函数就写在了activity中,对应于controller层。是不是很清晰。大家想过这样会有什么问题吗?显然是有的,不然为什么会有MVP和MVVM的诞生呢,是吧。问题就在于xml作为view层,控制能力实在太弱了,你想去动态的改变一个页面的背景,或者动态的隐藏/显示一个按钮,这些都没办法在xml中做,只能把代码写在activity中,造成了activity既是controller层,又是view层的这样一个窘境。大家回想一下自己写的代码,如果是一个逻辑很复杂的页面,activity或者fragment是不是动辄上千行呢?这样不仅写起来麻烦,维护起来更是噩梦。(当然看过Android源码的同学其实会发现上千行的代码不算啥,一个RecyclerView.class的代码都快上万行了呢。。)MVC还有一个重要的缺陷,大家看上面那幅图,view层和model层是相互可知的,这意味着两层之间存在耦合,耦合对于一个大型程序来说是非常致命的,因为这表示开发,测试,维护都需要花大量的精力。正因为MVC有这样那样的缺点,所以才演化出了MVP和MVVM这两种框架。**二、MVP**MVP作为MVC的演化,解决了MVC不少的缺点,对于Android来说,MVP的model层相对于MVC是一样的,而activity和fragment不再是controller层,而是纯粹的view层,所有关于用户事件的转发全部交由presenter层处理。下面还是让我们看图![Paste_Image.png](http://upload-images.jianshu.io/upload_images/5423625-53a5a00ab675f8ca.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)从图中就可以看出,最明显的差别就是view层和model层不再相互可知,完全的解耦,取而代之的presenter层充当了桥梁的作用,用于操作view层发出的事件传递到presenter层中,presenter层去操作model层,并且将数据返回给view层,整个过程中view层和model层完全没有联系。看到这里大家可能会问,虽然view层和model层解耦了,但是view层和presenter层不是耦合在一起了吗?其实不是的,对于view层和presenter层的通信,我们是可以通过接口实现的,具体的意思就是说我们的activity,fragment可以去实现实现定义好的接口,而在对应的presenter中通过接口调用方法。不仅如此,我们还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试。这就解决了MVC模式中测试,维护难的问题。当然,其实最好的方式是使用fragment作为view层,而activity则是用于创建view层和presenter层(presenter)的一个控制器。**三、MVVM**MVVM最早是由微软提出的![Paste_Image.png](http://upload-images.jianshu.io/upload_images/5423625-fef0d11ff52bf658.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)从图中看出,它和MVP的区别貌似不大,只不过是presenter层换成了viewmodel层,还有一点就是view层和viewmodel层是相互绑定的关系,这意味着当你更新viewmodel层的数据的时候,view层会相应的变动ui。我们很难去说MVP和MVVM这两个MVC的变种孰优孰劣,还是要具体情况具体分析。[](http://zjutkz.net/2016/04/13/选择恐惧症的福音!教你认清MVC,MVP和MVVM/#纸上得来终觉浅,绝知此事要躬行)纸上得来终觉浅,绝知此事要躬行对于程序员来说,空谈是最没效率的一种方式,相信大家看了我上面对于三种模式的分析,或多或少都会有点云里雾里,下面让我们结合代码来看看。让我们试想一下下面这个情景,用户点击一个按钮A,获取github上对应公司对应仓库中贡献排行第一的任的名字,然后我们还会有一个按钮B,用户点击按钮B,界面上排行第一的那个人的名字就会换成自己的。[](http://zjutkz.net/2016/04/13/选择恐惧症的福音!教你认清MVC,MVP和MVVM/#MVC-1)MVCMVC实现是最简单的。首先看对应view层的xml文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:androxmlns:tools=";

<Button android:text="get" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="get"/> <Button android:text="change" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="change"/> <TextView android: android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textSize="30sp"/> 

</LinearLayout> ```很简单,两个Button一个TextView

随后看对应controller层的activity

public class MainActivity extends AppCompatActivity { private ProcessDialog dialog; private Contributor contributor = new Contributor(); private TextView topContributor; private Subscriber<Contributor> contributorSub = new Subscriber<Contributor>() { @Override public void onStart() { showProgress(); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Contributor contributor) { MainActivity.this.contributor = contributor; topContributor.setText(contributor.login); dismissProgress(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); topContributor = findViewById(R.id.top_contributor); } public void get(View view){ getTopContributor("square", "retrofit"); } public void change(View view){ contributor.login = "zjutkz"; topContributor.setText(contributor.login); } public void getTopContributor(String owner,String repo){ GitHubApi.getContributors(owner, repo) .take .observeOn(AndroidSchedulers.mainThread .subscribeOn(Schedulers.newThread .map(new Func1<List<Contributor>, Contributor>() { @Override public Contributor call(List<Contributor> contributors) { return contributors.get .subscribe(contributorSub); } public void showProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.showMessage("正在加载..."); } public void dismissProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.dismiss(); } } ```我们看一下get()方法中调用的getTopContributor方法

public void getTopContributor(String owner,String repo){GitHubApi.getContributors(owner, repo).take.observeOn(AndroidSchedulers.mainThread.subscribeOn(Schedulers.newThread.map(new Func1<List<Contributor>, Contributor>() {

 @Override public Contributor call(List<Contributor> contributors) { return contributors.get .subscribe(contributorSub); 

} ```熟知rxjava和retrofit的同班应该都领会那是啥意思,要是对那八个开源库不熟知也没事,能够参照给 Android 开垦者的 福特ExplorerxJava 详明和用 Retrofit 2 简化 HTTP 央浼这两篇随笔。对于这里我们借使通晓这段代码的情趣便是去获取github上owner集团中的repo客栈里进献排名第一的特别人。进献者是经过Contributor那几个java bean存款和储蓄的。

public class Contributor { public String login; public int contributions; @Override public String toString() { return login   ", "   contributions; } } ```很简单,login表示贡献者的名字,contributor表示贡献的次数。然后通过rxjava的subscriber中的onNext()函数得到这个数据。

private Subscriber<Contributor> contributorSub = new Subscriber<Contributor>() {

@Override public void onStart() { showProgress(); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Contributor contributor) { MainActivity.this.contributor = contributor; topContributor.setText(contributor.login); dismissProgress(); } 

}; ```有关其余那多少个change开关的行事大家应该都看得懂,这里不另行了。好了,大家来回想叁回整个工艺流程。首先在xml中写好构造代码。其次,activity作为二个controller,里面的逻辑是监听客商点击按键并作出相应的操作。譬喻照准get按钮,做的办事就是调用GithubApi的法子去获取数据。GithubApi,Contributor等类则表示MVC中的model层,里面是数额和局地实际的逻辑操作。讲完了工艺流程再来看看难题,还记得咱们前面说的啊,MVC在Android上的采纳,一个涉笔成趣的标题正是activity的权力和权利过重,既是controller又是view。这里是怎么体现的吧?看了代码我们发掘中间有三个progressDialog,在加载数据的时候显得,加载完了后来撤消,逻辑其实是view层的逻辑,不过这一个大家不可能写到xml里面啊,包罗TextView.setTextView(卡塔尔,那几个也一样。大家只可以把那几个逻辑写到activity中,那就产生了activity的交汇,这一个例子大概辛亏,假设是三个千头万绪的页面吗?我们本人想象一下。MVP通过具体的代码我们清楚了MVC在Android上是怎么做事的,也了然了它的弱项,那MVP是什么样改良的吗?这里先向大家推荐github上的四个第三方库,通过这么些库大家能够很自在的落到实处MVP。好了,依然看代码吧。首先依旧xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andro xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android: android:orientation="vertical" tools:context=".ui.view.MainActivity" android:fitsSystemWindows="true"> <Button android:text="get" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="get"/> <Button android:text="change" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="change"/> <TextView android: android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textSize="30sp"/> </LinearLayout> ```这个和MVC是一样的,毕竟界面的形式是一样的嘛。接下去,我们看一个接口。

public interface ContributorView extends MvpView {

void onLoadContributorStart(); void onLoadContributorComplete(Contributor topContributor); void onChangeContributorName(String name); 

} ```其一接口起怎样效劳吧?还记得小编后边说的啊?MVP方式中,view层和presenter层靠的就是接口实行一而再三回九转,而具体的正是地方的那些了,里面定义的多个主意,第叁个是开首获取数据,第贰个是获取数据成功,第多少个是化名。我们的view层只要完结这么些接口就可以了。

下面看activity的代码

public class MainActivity extends MvpActivity<ContributorView,ContributorPresenter> implements ContributorView { private ProcessDialog dialog; private TextView topContributor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); topContributor = findViewById(R.id.top_contributor); } @NonNull @Override public ContributorPresenter createPresenter() { return new ContributorPresenter(); } public void get(View view){ getPresenter().get("square", "retrofit"); } public void change(View view){ getPresenter().change(); } @Override public void onLoadContributorStart() { showProgress(); } @Override public void onLoadContributorComplete(Contributor contributor) { topContributor.setText(contributor.toString; dismissProgress(); } @Override public void onChangeContributorName(String name) { topContributor.setText; } public void showProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.showMessage("正在加载..."); } public void dismissProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.dismiss(); } } ```它继承自MvpActivity,实现了刚才的ContributorView接口。继承的那个MvpActivity大家这里不用太关心主要是做了一些初始化和生命周期的封装。我们只要关心这个activity作为view层,到底是怎么工作的。

public void get(View view){getPresenter().get("square", "retrofit");}

public void change(View view){getPresenter().change();} ```get(卡塔尔(قطر‎和change(卡塔尔那三个章程是大家点击按键之后实践的,能够阅览,里面完完全全未有别的和model层逻辑相关的事物,只是简短的嘱托给了presenter,那大家再看看presenter层做了怎样

public class ContributorPresenter extends MvpBasePresenter<ContributorView> { private Subscriber<Contributor> contributorSub = new Subscriber<Contributor>() { @Override public void onStart() { ContributorView view = getView(); if(view != null){ view.onLoadContributorStart(); } } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Contributor topContributor) { ContributorView view = getView(); if(view != null){ view.onLoadContributorComplete(topContributor); } } }; public void get(String owner,String repo){ GitHubApi.getContributors(owner, repo) .take .observeOn(AndroidSchedulers.mainThread .subscribeOn(Schedulers.newThread .map(new Func1<List<Contributor>, Contributor>() { @Override public Contributor call(List<Contributor> contributors) { return contributors.get .subscribe(contributorSub); } public void change(){ ContributorView view = getView(); if(view != null){ view.onChangeContributorName; } } } ```其实就是把刚才MVC中activity的那部分和model层相关的逻辑抽取了出来,并且在相应的时机调用ContributorView接口对应的方法,而我们的activity是实现了这个接口的,自然会走到对应的方法中。好了,我们来捋一捋。首先,和MVC最大的不同,MVP把activity作为了view层,通过代码也可以看到,整个activity没有任何和model层相关的逻辑代码,取而代之的是把代码放到了presenter层中,presenter获取了model层的数据之后,通过接口的形式将view层需要的数据返回给它就OK了。这样的好处是什么呢?首先,activity的代码逻辑减少了,其次,view层和model层完全解耦,具体来说,如果你需要测试一个http请求是否顺利,你不需要写一个activity,只需要写一个java类,实现对应的接口,presenter获取了数据自然会调用相应的方法,相应的,你也可以自己在presenter中mock数据,分发给view层,用来测试布局是否正确。[](http://zjutkz.net/2016/04/13/选择恐惧症的福音!教你认清MVC,MVP和MVVM/#MVVM-1)MVVM首先在看这段内容之前,你需要保证你对data binding框架有基础的了解。不了解的同学可以去看下这篇文章。在接下去让我们开始探索MVVM,MVVM最近在Android上可谓十分之火,最主要的原因就是谷歌推出了data binding这个框架,可以轻松的实现MVVM。但是,我在网上查阅关于Android的data binding资料的时候,发现国内有很多人都误解了,首先,我们从一篇错误的文章开始。当然我在这里引用这篇文章也是对事不对人,如果对文章的作者产生了不好的影响我这里说一声抱歉。上面那篇文章是一个关于data binding的使用,看起来很美好,但是,其中有一个错误可以说是非常,非常,非常严重的。![1460565976130825.png](http://upload-images.jianshu.io/upload_images/5423625-5397a479448a3103.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)它竟然说data binding的viewmodel层是binding类,其实不止是这篇文章,其他有一些开发者写的关于data binding的文章里都犯了一样的错误。大家如果也有这样的概念,请务必纠正过来!!说完了错误的概念,那data binding中真正的viewmodel是什么呢?我们还是以之前MVC,MVP的那个例子做引导。首先是view层,这没啥好说的,和MVP一样,view层就是xml和activity。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:androxmlns:tools=";

<Button android:text="get" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="get"/> <Button android:text="change" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="change"/> <TextView android: android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textSize="30sp"/> 

</LinearLayout> ```

public class MainActivity extends AppCompatActivity { private Subscriber<Contributor> contributorSub = new Subscriber<Contributor>() { @Override public void onStart() { showProgress(); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Contributor contributor) { binding.setContributor(contributor); dismissProgress(); } }; private ProcessDialog dialog; private MvvmActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.mvvm_activity_main); } public void get(View view){ getContributors("square", "retrofit"); } public void change(View view){ if(binding.getContributor() != null){ binding.getContributor().setLogin; } } public void showProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.showMessage("正在加载..."); } public void dismissProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.dismiss(); } public void getContributors(String owner,String repo){ GitHubApi.getContributors(owner, repo) .take .observeOn(AndroidSchedulers.mainThread .subscribeOn(Schedulers.newThread .map(new Func1<List<Contributor>, Contributor>() { @Override public Contributor call(List<Contributor> contributors) { return contributors.get .subscribe(contributorSub); } } ```如果你对data binding框架是有了解的,上面的代码你能轻松的看懂。那model层又是什么呢?当然就是那些和数据相关的类,GithubApi等等。重点来了,viewmodel层呢?好吧,viewmodel层就是是Contributor类!大家不要惊讶,我慢慢的来说。

public class Contributor extends BaseObservable{

private String login; private int contributions; @Bindable public String getLogin(){ return login; } @Bindable public int getContributions(){ return contributions; } public void setLogin(String login){ this.login = login; notifyPropertyChanged; } public void setContributions(int contributions){ this.contributions = contributions; notifyPropertyChanged(BR.contributions); } @Override public String toString() { return login   ", "   contributions; } 

} ```大家能够看来,Contributor和MVP比较,世袭自了BaseObservable,有底子的同室都知晓那是为了当Contributor内部的variable纠正的时候ui能够一齐的作出响应。

本人干吗说Contributor是叁个viewmodel呢。大家还记得viewmodel的概念呢?view和viewmodel相互绑定在协同,viewmodel的改观会一同到view层,进而view层作出响应。那不正是Contributor和xml中那个组件成分的关联呢?所以,大家不要被binding类吸引了,data binding框架中的viewmodel是投机定义的那个看似是model类的东西!比方这里的Contributor!

话提起此地,那binding类又是怎么样啊?其实具体对应到在此以前MVVM的那张图就很好通晓了,大家想转手,binding类的办事是怎么着?

binding = DataBindingUtil.setContentView(this, R.layout.mvvm_activity_main); binding.setContributor(contributor); ```首先,binding要通过DataBindingUtil.setContentView()方法将xml,也就是view层设定。接着,通过setXXX()方法将viewmodel层注入进去。由于这两个工作,view层和viewmodel层(contributor)绑定在了一起。好了,大家知道了吗,binding类,其实就是上图中view和viewmodel中间的那根线啊!![](http://zjutkz.net/2016/04/13/选择恐惧症的福音!教你认清MVC,MVP和MVVM/#真理在荒谬被证实以前,都只是暗室里的装饰)真理在荒谬被证实以前,都只是暗室里的装饰前面讨论了MVC,MVP和MVVM具体的实现方案,大家肯定都了解了它们三者的关系和使用方式。但是,这里我想说,不要把一个框架看作万能的,其实MVP和MVVM都是有自己的缺陷的!下面我一一来说。[](http://zjutkz.net/2016/04/13/选择恐惧症的福音!教你认清MVC,MVP和MVVM/#MVP-2)MVPMVP的问题在于,由于我们使用了接口的方式去连接view层和presenter层,这样就导致了一个问题,如果你有一个逻辑很复杂的页面,你的接口会有很多,十几二十个都不足为奇。想象一个app中有很多个这样复杂的页面,维护接口的成本就会非常的大。这个问题的解决方案就是你得根据自己的业务逻辑去斟酌着写接口。你可以定义一些基类接口,把一些公共的逻辑,比如网络请求成功失败,toast等等放在里面,之后你再定义新的接口的时候可以继承自那些基类,这样会好不少。[](http://zjutkz.net/2016/04/13/选择恐惧症的福音!教你认清MVC,MVP和MVVM/#MVVM-2)MVVMMVVM的问题呢,其实和MVC有一点像。data binding框架解决了数据绑定的问题,但是view层还是会过重,大家可以看我上面那个MVVM模式下的activity

public class MainActivity extends AppCompatActivity {

private Subscriber<Contributor> contributorSub = new Subscriber<Contributor>() { @Override public void onStart() { showProgress(); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Contributor contributor) { binding.setContributor(contributor); dismissProgress(); } }; private ProcessDialog dialog; private MvvmActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.mvvm_activity_main); } public void get(View view){ getContributors("square", "retrofit"); } public void change(View view){ if(binding.getContributor() != null){ binding.getContributor().setLogin; } } public void showProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.showMessage("正在加载..."); } public void dismissProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.dismiss(); } public void getContributors(String owner,String repo){ GitHubApi.getContributors(owner, repo) .take .observeOn(AndroidSchedulers.mainThread .subscribeOn(Schedulers.newThread .map(new Func1<List<Contributor>, Contributor>() { @Override public Contributor call(List<Contributor> contributors) { return contributors.get .subscribe(contributorSub); } 

} ```世家有未有觉察,activity在MVVM中应该是view层的,不过中间却和MVC相通写了对model的管理。有人会说你能够把对model的拍卖放到viewmodel层中,这样不是更切合MVVM的安排意见吗?那样真的能够,但是progressDialog的show和dismiss呢?你怎么在viewmodel层中决定?那是view层的东西啊,何况在xml中也未有,笔者百依百顺会有解决的方案,可是大家有未有一种特别方便人民群众的不二诀窍呢?王燕国远其修远兮,吾将上下而求索其实,真正的最棒实行都以人想出去的,大家怎么不构成一下MVP和MVVM的特色吗?其实谷歌(GoogleState of Qatar一度做了这么的事,大家能够看下那几个。对的,就是MVP data binding,大家得以选择presenter去做和model层的通讯,何况动用data binding去轻巧的bind data。还是让我们看代码吧。首先依旧view层。

<layout xmlns:andro> <data> <variable name="contributor" type="zjutkz.com.mvpdatabinding.viewmodel.Contributor"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android: android:orientation="vertical" android:fitsSystemWindows="true"> <Button android: android:text="get" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="get"/> <Button android: android:text="change" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="change"/> <TextView android: android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textSize="30sp" android:text="@{contributor.login}"/> </LinearLayout> </layout> ```

public class MainActivity extends MvpActivity<ContributorView,ContributorPresenter> implements ContributorView {

private ProcessDialog dialog; private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); } @NonNull @Override public ContributorPresenter createPresenter() { return new ContributorPresenter(); } public void get(View view){ getPresenter().get("square", "retrofit"); } public void change(View view){ if(binding.getContributor() != null){ binding.getContributor().setLogin; } } @Override public void onLoadContributorStart() { showProgress(); } @Override public void onLoadContributorComplete(Contributor contributor) { binding.setContributor(contributor); dismissProgress(); } public void showProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.showMessage("正在加载..."); } public void dismissProgress(){ if(dialog == null){ dialog = new ProcessDialog; } dialog.dismiss(); } 

} ```然后是presenter层

public class ContributorPresenter extends MvpBasePresenter<ContributorView> { private Subscriber<Contributor> contributorSub = new Subscriber<Contributor>() { @Override public void onStart() { ContributorView view = getView(); if(view != null){ view.onLoadContributorStart(); } } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Contributor topContributor) { ContributorView view = getView(); if(view != null){ view.onLoadContributorComplete(topContributor); } } }; public void get(String owner,String repo){ GitHubApi.getContributors(owner, repo) .take .observeOn(AndroidSchedulers.mainThread .subscribeOn(Schedulers.newThread .map(new Func1<List<Contributor>, Contributor>() { @Override public Contributor call(List<Contributor> contributors) { return contributors.get .subscribe(contributorSub); } } ```model层就是GithubApi等等。我们使用了data binding框架去节省了类似findViewById和数据绑定的时间,又使用了presenter去将业务逻辑和view层分离。当然这也不是固定的,你大可以在viewmodel中实现相应的接口,presenter层的数据直接发送到viewmodel中,在viewmodel里更新,因为view和viewmodel是绑定的,这样view也会相应的作出反应。说到这里,我还是想重复刚才的那句话,最佳实践都是人想出来的,用这些框架根本的原因也是为了尽量低的耦合性和尽量高的可复用性。实例代码下载:https://github.com/gb0302/MvPDemo

本文由金沙js77888发布于金沙js77888,转载请注明出处:因为假如你不关心架构

关键词: js333金沙线路 浅谈 MVC MVP