单例模式能够说是最容易理解的模式了,也是应用最广的模式之一,先看看定义吧。算法
定义:确保单例类只有一个实例,而且这个单例类提供一个函数接口让其余类获取到这个惟一的实例。数据库
何时须要使用单例模式呢:若是某个类,建立时须要消耗不少资源,即new出这个类的代价很大;或者是这个类占用不少内存,若是建立太多这个类实例会致使内存占用太多。设计模式
关于单例模式,虽然很简单,无需过多的解释,可是这里还要提个醒,其实单例模式里面有不少坑。咱们去会会单例模式。最简单的单例模式以下:安全
public class Singleton{ private static Singleton instance; //将默认的构造函数私有化,防止其余类手动new private Singleton(){}; public static Singleton getInstance(){ if(instance==null) instance=new Singleton(); return instatnce; } }
instance
多是
null
,可能你会想,这有什么可贵,直接在
getInstance()
函数上加
sychronized
关键字不就行了。但是你想过没有,每次调用
getInstance()
时都要执行同步,这带来不必的性能上的消耗。注意,在方法上加
sychronized
关键字时,一个线程访问这个方法时,其余线程没法同时访问这个类其余
sychronized
方法。的咱们看看另一种实现:
public class Singleton{ private static Singleton instance; //将默认的构造函数私有化,防止其余类手动new private Singleton(){}; public static Singleton getInstance(){ if(instance==null){ sychronized(Singleton.class){ if(instance==null) instance=new Singleton(); } } return instatnce; } }
为何须要2次判断是否为空呢?第一次判断是为了不没必要要的同步,第二次判断是确保在此以前没有其余线程进入到sychronized块建立了新实例。这段代码看上去很是完美,可是,,,却有隐患!问题出如今哪呢?主要是在instance=new Singleton();
这段代码上。这段代码会编译成多条指令,大体上作了3件事:微信
(1)给Singleton实例分配内存
(2)调用Singleton()构造函数,初始化成员字段
(3)将instance对象指向分配的内存(此时instance就不是null啦~)网络
上面的(2)和(3)的顺序没法获得保证的,也就是说,JVM可能先初始化实例字段再把instance
指向具体的内存实例,也可能先把instance
指向内存实例再对实例进行初始化成员字段。考虑这种状况:一开始,第一个线程执行instance=new Singleton();
这句时,JVM先指向一个堆地址,而此时,又来了一个线程2,它发现instance
不是null
,就直接拿去用了,可是堆里面对单例对象的初始化并无完成,最终出现错误~ 。
看看另一种方式:数据结构
public class Singleton{ private volatile static Singleton instance; //将默认的构造函数私有化,防止其余类手动new private Singleton(){}; public static Singleton getInstance(){ if(instance==null){ sychronized(Singleton.class){ if(instance==null) instance=new Singleton(); } } return instatnce; } }
相比前面的代码,这里只是对instance
变量加了一个volatile
关键字volatile
关键字的做用是:线程每次使用到被volatile
关键字修饰的变量时,都会去堆里拿最新的数据。换句话说,就是每次使用instance时,保证了instance是最新的。注意:volatile
关键字并不能解决并发的问题,关于volatile
请查看其它相关文章。可是volatile
能解决咱们这里的问题。微信开发
那么在安卓中哪些地方用到了单例模式呢?其实,咱们在调用系统服务时拿到的Binder对象就是个单例。好比:多线程
//获取WindowManager服务引用 WindowManager wm = (WindowManager)getSystemService(getApplication().WINDOW_SERVICE);
其内部是经过单例的方式返回的,因为单例模式较简单,这里不去深究。
Builder模式是什么状况呢?我不想去提它的定义,由于他的定义:将一个复杂对象的构造与它的表示分离,使得一样的构造过程能够建立不一样的表示。好吧,我仍是提了。可是看了这个定义并无什么luan用。咱们看看具体在什么状况下用到Builder模式:主要是在建立某个对象时,须要设定不少的参数(经过setter方法),可是这些参数必须按照某个顺序设定,或者是设置步骤不一样会获得不一样结果。举个很是简单的例子:
public class MyData{ private int id; private String num; public void Test(){ } public void setId(int id){ this.id=id; } public void setNum(String num){ this.num=num+"id"; } }
固然了,没有人会这么去写代码。这里只是举例子,或者是有时候不少参数有这种相似的依赖关系时,经过构造函数未免太多参数了。回到主题,就是若是是上面的代码,该怎么办呢?你可能会说,那还不简单,先调用setId
函数,再调用setNum
函数。是的,没错。但是,万一你一不当心先调用了setNum
呢?这是比较简单的示例,若是是比较复杂的,有不少变量之间依赖的关系,那你每次都得当心翼翼的把各个函数的执行步骤写正确。
咱们看看Builder模式是怎么去作的:
public class MyBuilder{ private int id; private String num; public MyData build(){ MyData d=new MyData(); d.setId(id); d.setNum(num); return t; } public MyBuilder setId(int id){ this.id=id; return this; } public MyBuilder setNum(String num){ this.num=num; return this; } } public class Test{ public static void main(String[] args){ MyData d=new MyBuilder().setId(10).setNum("hc").build(); } }
注意到,Builer
类的setter
函数都会返回自身的引用this
,这主要是用于链式调用,这也是Builder
设计模式中的一个很明显的特征。
Android中用过的代码来记忆
记忆我这个例子没啥意义,咱们前面说过,要经过Android中用过的代码来记忆,这样才能够不用死记硬背。那么在Android中哪里用到了Builder设计模式呢?哈哈~在建立对话框时,是否是跟上面有点相似呢?
AlertDialog.Builer builder=new AlertDialog.Builder(context); builder.setIcon(R.drawable.icon) .setTitle("title") .setMessage("message") .setPositiveButton("Button1", new DialogInterface.OnclickListener(){ public void onClick(DialogInterface dialog,int whichButton){ setTitle("click"); } }) .create() .show();
这里的create()函数就想到上面代码中的build函数。看到这里是否是在心里中默默的把Builder设计模式拿下了?你并不用死记硬背~
原型设计模式很是简单,就是将一个对象进行拷贝。对于类A实例a,要对a进行拷贝,就是建立一个跟a同样的类型A的实例b,而后将a的属性所有复制到b。
何时会用到原型模式呢?我我的认为,能够在类的属性特别多,可是又要常常对类进行拷贝的时候能够用原型模式,这样代码比较简洁,并且比较方便。
另外要注意的是,还有深拷贝和浅拷贝。深拷贝就是把对象里面的引用的对象也要拷贝一份新的对象,并将这个新的引用对象做为拷贝的对象引用。说的比较绕哈~,举个例子,假设A类中有B类的引用b,如今须要对A类实例进行拷贝,那么深拷贝就是,先对b进行一次拷贝获得nb,而后把nb做为A类拷贝的对象的引用,如此一层一层迭代拷贝,把全部的引用都拷贝结束。浅拷贝则不是。
原型模式比较简单,看看Android怎么运用原型模式:
Uri uri=Uri.parse("smsto:10086"); Intent shareIntent=new Intent(Intent.ACTION_SENDTO,uri); //克隆副本 Intent intent=(Intetn)shareIntent.clone(); startActivity(intent);
或许咱们平时不会这么去写,可是Intent
对象确实提供了原型模式的函数clone()
定义:定义一个建立对象的接口,让子类决定实例化哪一个类
先看一个例子:
public abstract class Product{ public abstract void method(); } public class ConcreteProductA extends Prodect{ public void method(){ System.out.println("我是产品A!"); } } public class ConcreteProductB extends Prodect{ public void method(){ System.out.println("我是产品B!"); } } public abstract class Factory{ public abstract Product createProduct(); } public class MyFactory extends Factory{ public Product createProduct(){ return new ConcreteProductA(); } }
看到上面的代码,是否是以为工厂模式很简单呢?还能够经过传参的方式,让MyFactory的createProduct方法根据传入的参数决定是建立ConcreteProductA仍是ConcreteProductB。
一样的,咱们不但愿记住这个例子,而是经过Android中的代码来记忆:
其实,在getSystemService
方法中就是用到了工厂模式,他就是根据传入的参数决定建立哪一个对象,固然了,因为返回的都是以单例模式存在的对象,所以不用new了,直接把单例返回就好。
public Object getSystemService(String name) { if (getBaseContext() == null) { throw new IllegalStateException("System services not available to Activities before onCreate()"); } //........ if (WINDOW_SERVICE.equals(name)) { return mWindowManager; } else if (SEARCH_SERVICE.equals(name)) { ensureSearchManager(); return mSearchManager; } //....... return super.getSystemService(name); }
抽象工厂模式:为建立一组相关或者是相互依赖的对象提供一个接口,而不须要制定他们的具体类
看个例子吧,将它跟工厂方法模式作个对比:
public abstract class AbstractProductA{ public abstract void method(); } public abstract class AbstractProdectB{ public abstract void method(); } public class ConcreteProductA1 extends AbstractProductA{ public void method(){ System.out.println("具体产品A1的方法!"); } } public class ConcreteProductA2 extends AbstractProductA{ public void method(){ System.out.println("具体产品A2的方法!"); } } public class ConcreteProductB1 extends AbstractProductB{ public void method(){ System.out.println("具体产品B1的方法!"); } } public class ConcreteProductB2 extends AbstractProductB{ public void method(){ System.out.println("具体产品B2的方法!"); } } public abstract class AbstractFactory{ public abstract AbstractProductA createProductA(); public abstract AbstractProductB createProductB(); } public class ConcreteFactory1 extends AbstractFactory{ public AbstractProductA createProductA(){ return new ConcreteProductA1(); } public AbstractProductB createProductB(){ return new ConcreteProductB1(); } } public class ConcreteFactory2 extends AbstractFactory{ public AbstractProductA createProductA(){ return new ConcreteProductA2(); } public AbstractProductB createProductB(){ return new ConcreteProductB2(); } }
其实Android源码中对抽象工厂出现的比较少,好在抽象工厂方法并不复杂,很容易记住,咱们能够从Service中去理解,Service的onBind方法能够当作是一个工厂方法,从framework角度来看Service,能够当作是一个具体的工厂,这至关于一个抽象工厂方法模式的雏形。
public class BaseService extends Service{ @Nullable @Override public IBinder onBind(Intent intent){ return new Binder(); } }
定义:有一系列的算法,将每一个算法封装起来(每一个算法能够封装到不一样的类中),各个算法之间能够替换,策略模式让算法独立于使用它的客户而独立变化。
举个例子来理解吧,好比,你如今又不少排序算法:冒泡、希尔、归并、选择等等。咱们要根据实际状况来选择使用哪一种算法,有一种常见的方法是,经过if…else或者case…等条件判断语句来选择。可是这个类的维护成本会变高,维护时也容易发生错误。
如何使用策略模式呢,我不打算写示例代码了,简单描述一下,就将前面说的算法选择进行描述。咱们能够定义一个算法抽象类AbstractAlgorithm,这个类定义一个抽象方法sort()。每一个具体的排序算法去继承AbstractAlgorithm类并重写sort()实现排序。在须要使用排序的类Client类中,添加一个setAlgorithm(AbstractAlgorithm al);方法将算法设置进去,每次Client须要排序而是就调用al.sort()。
不知道简单描述能不能让你理解~
看看Android中哪里出现了策略模式,其中在属性动画中使用时间插值器的时候就用到了。在使用动画时,你能够选择线性插值器LinearInterpolator、加速减速插值器AccelerateDecelerateInterpolator、减速插值器DecelerateInterpolator以及自定义的插值器。这些插值器都是实现根据时间流逝的百分比来计算出当前属性值改变的百分比。经过根据须要选择不一样的插值器,实现不一样的动画效果。这些比较好理解,就不去粘贴Android源码了。
状态模式中,行为是由状态来决定的,不一样状态下有不一样行为。状态模式和策略模式的结构几乎是如出一辙的,主要是他们表达的目的和本质是不一样。状态模式的行为是平行的、不可替换的,策略模式的行为是彼此独立可相互替换的。
举个例子把,好比电视,电视有2个状态,一个是开机,一个是关机,开机时能够切换频道,关机时切换频道不作任何响应。
public interface TvState{ public void nextChannerl(); public void prevChannerl(); public void turnUp(); public void turnDown(); } public class PowerOffState implements TvState{ public void nextChannel(){} public void prevChannel(){} public void turnUp(){} public void turnDown(){} } public class PowerOnState implements TvState{ public void nextChannel(){ System.out.println("下一频道"); } public void prevChannel(){ System.out.println("上一频道"); } public void turnUp(){ System.out.println("调高音量"); } public void turnDown(){ System.out.println("调低音量"); } } public interface PowerController{ public void powerOn(); public void powerOff(); } public class TvController implements PowerController{ TvState mTvState; public void setTvState(TvStete tvState){ mTvState=tvState; } public void powerOn(){ setTvState(new PowerOnState()); System.out.println("开机啦"); } public void powerOff(){ setTvState(new PowerOffState()); System.out.println("关机啦"); } public void nextChannel(){ mTvState.nextChannel(); } public void prevChannel(){ mTvState.prevChannel(); } public void turnUp(){ mTvState.turnUp(); } public void turnDown(){ mTvState.turnDown(); } } public class Client{ public static void main(String[] args){ TvController tvController=new TvController(); tvController.powerOn(); tvController.nextChannel(); tvController.turnUp(); tvController.powerOff(); //调高音量,此时不会生效 tvController.turnUp(); } }
在Android源码中,哪里有用到状态模式呢?其实不少地方用到了,举一个地方例子,就是WIFI管理模块。当WIFI开启时,自动扫描周围的接入点,而后以列表的形式展现;当wifi关闭时则清空。这里wifi管理模块就是根据不一样的状态执行不一样的行为。因为代码太多,我就不手打敲入了~咱们只要知道大体Android里面在哪里用到了以及大概是怎么用的就好。
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者直接的耦合关系,将这些对象连成一条链,并沿这条链传递该请求,直到有对象处理它为止。
相信聪明的你很容易理解吧,基本不须要例子来解释了,直接进如到Android源码中哪里用到了责任链:在Android处理点击事件时,父View先接收到点击事件,若是父View不处理则交给子View,依次往下传递~
定义:给定一个语言,定义它的语法,并定义一个解释器,这个解释器用于解析语言。
从定义中看起来比较抽象,其实,很简单,很容易理解!就是至关于自定义一个格式的文件,而后去解析它。不用理解的那么复杂!
咱们看看Android中哪里用到了,从咱们第一次学Android时就知道,四大组件须要在AndroidManifest.xml
中定义,其实AndroidManifest.xml
就定义了<Activity>
,<Service>
等标签(语句)的属性以及其子标签,规定了具体的使用(语法),经过PackageManagerService(解释器)进行解析。
定义:命令模式将每一个请求封装成一个对象,从而让用户使用不一样的请求把客户端参数化;将请求进行排队或者记录请求日志,以及支持可撤销操做。
举个例子来理解:当咱们点击“关机”命令,系统会执行一系列操做,好比暂停事件处理、保存系统配置、结束程序进程、调用内核命令关闭计算机等等,这些命令封装从不一样的对象,而后放入到队列中一个个去执行,还能够提供撤销操做。
那么Android中哪里用到了命令模式呢?在framework层还真很少。可是在底层却用到了,一个比较典型的例子就是在Android事件机制中,底层逻辑对事件的转发处理。每次的按键事件会被封装成NotifyKeyArgs对象。经过InputDispatcher封装具体的事件操做。
定义:定义了对象之间的一对多的关系,其实就是1对n,当“1”发生变化时,“n”所有获得通知,并更新。
观察者模式一个比较经典的应用就是:订阅——发布系统。很容易理解,发布消息时,将消息发送给每一个订阅者。咱们经常使用的微信公众号就是典型,当咱们关注某个公众号时,每当公众号推送消息时,咱们就会去接收到消息,固然了,每一个订阅(关注)公众号的的人都能接收到公众号推送的消息。
那么Android哪里用到了观察者模式呢?咱们看看ListView的适配器,有个函数notifyDataSetChanged()
函数,这个函数其实就是通知ListView的每一个Item,数据源发生了变化,请各位Item从新刷新一下。
备忘录模式定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在对象以外保存这个状态,这样,之后就可将对象恢复到原先保存的状态中。
其实就是至关于一个提早备份,一旦出现啥意外,可以恢复。像咱们平时用的word软件,意外关闭了,它能帮咱们恢复。其实就是它自动帮咱们备份过。
那么Android哪里用到了备忘录模式呢?Activity
的onSaveInstanceState
和onRestoreInstanceState
就是用到了备忘录模式,分别用于保存和恢复。
迭代器模式定义:提供一种方法顺序访问一个容器对象中的各个元素,而不须要暴露该对象的内部表示。
相信熟悉Java的你确定知道,Java中就有迭代器Iterator
类,本质上说,它就是用迭代器模式。
按照惯例,看看Android中哪里用到了迭代器模式,Android源码中,最典型的就是Cursor
用到了迭代器模式,当咱们使用SQLiteDatabase
的query
方法时,返回的就是Cursor
对象,经过以下方式去遍历:
cursor.moveToFirst(); do{ //cursor.getXXX(int); }while(cursor.moveToNext);
定义:定义一个操做中的算法框架,而将一些步骤延迟到子类中,使得子类能够不改变一个算法的结构便可重定义该算法的某些特定的步骤。
不用解释太多,感受越解释越糊涂,直接拿Android中的源码来讲事!
咱们知道,启动一个Activity
过程很是复杂,若是让开发者每次本身去调用启动Activity过程无疑是一场噩梦。好在启动Activity
大部分代码时不一样的,可是有不少地方须要开发者定制。也就是说,总体算法框架是相同的,可是将一些步骤延迟到子类中,好比Activity
的onCreate
、onStart
等等。这样子类不用改变总体启动Activity
过程便可重定义某些具体的操做了~。
定义:封装一些做用于某种数据结构中各元素的操做,它能够在不改变这个数据结构的前提下定义做用于这些元素的新的操做。
访问者模式是23种设计模式中最复杂的一个,但他的使用率并不高,大部分状况下,咱们不须要使用访问者模式,少数特定的场景才须要。
Android中运用访问者模式,其实主要是在编译期注解中,编译期注解核心原理依赖APT(Annotation Processing Tools),著名的开源库好比ButterKnife、Dagger、Retrofit都是基于APT。APT的详细使用这里不提,后面我会写关于APT相关的文章,敬请期待~
定义:中介者模式包装了一系列对象相互做用的方式,使得这些对象没必要相互明显调用,从而使他们能够轻松耦合。当某些对象之间的做用发生改变时,不会当即影响其余的一些对象之间的做用保证这些做用能够彼此独立的变化,中介者模式将多对多的相互做用转为一对多的相互做用。
何时用中介者模式呢?其实,中介者对象是将系统从网状结构转为以调停者为中心的星型结构。
举个简单的例子,一台电脑包括:CPU、内存、显卡、IO设备。其实,要启动一台计算机,有了CPU和内存就够了。固然,若是你须要链接显示器显示画面,那就得加显卡,若是你须要存储数据,那就要IO设备,可是这并非最重要的,它们只是分割开来的普通零件而已,咱们须要同样东西把这些零件整合起来,变成一个完总体,这个东西就是主板。主板就是起到中介者的做用,任何两个模块之间的通讯都会通过主板协调。
那么Android中那些地方用到了中介者模式呢?在Binder
机制中,就用到了中介者模式,对Binder
不是很熟悉的童鞋请参考个人《 简单明了,完全地理解Binder》。咱们知道系统启动时,各类系统服务会向ServiceManager
提交注册,即ServiceManager
持有各类系统服务的引用 ,当咱们须要获取系统的Service
时,好比ActivityManager
、WindowManager
等(它们都是Binder
),首先是向ServiceManager
查询指定标示符对应的Binder,再由ServiceManager
返回Binder
的引用。而且客户端和服务端之间的通讯是经过Binder驱动来实现,这里的ServiceManager
和Binder
驱动就是中介者。
定义:为其余类提供一种代理以控制这个对象的访问。
其实代理模式咱们平时用的也比较多,其实比较好理解,就是当咱们须要对一个对象进行访问时,咱们不直接对这个对象进行访问,而是访问这个类的代理类,代理类能帮咱们执行咱们想要的操做。代理模式比较容易理解,既然你来看这篇文章相信你对代理模式不陌生。
咱们直接看看代理模式在Android中的应用,若是你查看AIDL生成的代码就知道,它会根据当前的线程判断是否要跨进程访问,若是不须要跨进程就直接返回实例,若是须要跨进程则返回一个代理,这个代理干什么事情呢?咱们在《 简单明了,完全地理解Binder》提到,在跨进程通讯时,须要把参数写入到Parcelable对象,而后再执行transact函数,咱们要写的代码挺多的。AIDL经过生成一个代理类,代理类中自动帮咱们写好这些操做。
定义:将对象组成成树形结构,以表示“部分-总体”的层次结构,使得用户对单个对象和组合对象的使用具备一致性。
上面的定义不太好理解,咱们直接从Android中用到的组合模式提及。咱们知道,Android中View的结构是树形结构,每一个ViewGroup包含一系列的View,而ViewGroup自己又是View。这是Android中很是典型的组合模式。
定义:把一个类的接口变换成客户端所期待的另外一个接口,从而使本来因接口不匹配而没法在一块儿工做的两个类可以在一块儿工做。
其实适配器模式很容易理解,咱们在Android开发时也常常用到。比较典型的有ListView和RecyclerView。为何ListView须要使用适配器呢?主要是,ListView只关心它的每一个ItemView,而不关心这个ItemView具体显示的是什么。而咱们的数据源存放的是要显示的内容,它保存了每个ItemView要显示的内容。ListView和数据源之间没有任何关系,这时候,须要经过适配器,适配器提供getView方法给ListView使用,每次ListView只需提供位置信息给getView函数,而后getView函数根据位置信息向数据源获取对应的数据,根据数据返回不一样的View。
定义:动态的给一个对象添加额外的智者,就增长功能来讲,装饰模式比子类继承的方式更灵活。
经过简单代码来理解装饰模式:
public abstract class Component{ public abstract void operate(); } public class ConcreteComponent extends Component{ public void operate(){ //具体的实现 } } public class Decorator{ private Component component; public Decorator(Component component){ this.component=component; } public void operate(){ operateA(); component.operate(); operateB(); } public void operateA(){ //具体操做 } public void operateB(){ //具体操做 } }
那么在Android哪里出现了装饰模式呢?咱们平时常常用到Context类,可是其实Context类只是个抽象类,具体实现是ContextImpl,那么谁是ContextImpl的装饰类呢?咱们知道Activity是个Context,可是Activity 并非继承于Context,而是继承于ContextThremeWrapper.而ContextThremeWrapper继承于ContextWrapper,ContextWrapper继承Context.说了这么多,跟装饰模式有啥关系?主要是引入ContextWrapper这个类。ContextWrapper内部有个Context引用mContext,而且ContextWrapper中对Context的每一个方法都有实现,在实现中调用的就是mContext相同的方法。
定义:使用享元对象有效地支持大量的细粒度对象。
享元模式咱们平时接触真的不少,好比Java中的常量池,线程池等。主要是为了重用对象。
在Android哪里用到了享元模式呢?线程通讯中的Message,每次咱们获取Message时调用Message.obtain()
其实就是从消息池中取出可重复使用的消息,避免产生大量的Message对象。
定义:要求一个子系统的外部与其内部的通讯必须经过一个统一的对象进行。
怎么理解呢,举个例子,咱们在启动计算机时,只需按一下开关键,无需关系里面的磁盘、内存、cpu、电源等等这些如何工做,咱们只关心他们帮我启动好了就行。实际上,因为里面的线路太复杂,咱们也没办法去具体了解内部电路如何工做。主机提供惟一一个接口“开关键”给用户就好。
那么Android哪里使用到了外观模式呢?依然回到Context,Android内部有不少复杂的功能好比startActivty、sendBroadcast、bindService等等,这些功能内部的实现很是复杂,若是你看了源码你就能感觉获得,可是咱们无需关心它内部实现了什么,咱们只关心它帮咱们启动Activity,帮咱们发送了一条广播,绑定了Activity等等就够了。
定义:将抽象部分与实现部分分离,使他们独立地进行变化。
其实就是,一个类存在两个维度的变化,且这两个维度都须要进行扩展。
在Android中桥接模式用的不少,举个例子,对于一个View来讲,它有两个维度的变化,一个是它的描述好比Button、TextView等等他们是View的描述维度上的变化,另外一个维度就是将View真正绘制到屏幕上,这跟Display、HardwareLayer和Canvas有关。这两个维度能够当作是桥接模式的应用。
MVC
全称为Model-View-Controller,也就是模型-视图-控制器。MVC结构以下图所示:
在Android中对MVC的应用很经典,咱们的布局文件如main.xml就是对应View层,本地的数据库数据或者是网络下载的数据就是对应Model层,而Activity对应Controller层。
MVP
MVP全称为Model View Presenter,目前MVP在Android应用开发中愈来愈重要了,它的结构图以下:
它下降了View与Model之间的耦合。完全将View与Model分离。MVP不是一种标准化的模式,它由不少种实现。
MVVM
全称是Mode View ViewModel,它的结构以下所示:
咱们在使用ListView时,会自定义一个ViewHolder,在RecyclerView中是必须使用ViewHolder,这主要是提升性能,由于不须要每次去调用findViewById来获取View。其实ViewHolder就是个ViewModel。