1、观察者模式(Observer Pattern)
成都创新互联公司技术团队10年来致力于为客户提供成都网站设计、做网站、成都外贸网站建设公司、成都品牌网站建设、网络营销推广、搜索引擎SEO优化等服务。经过多年发展,公司拥有经验丰富的技术团队,先后服务、推广了上1000家网站,包括各类中小企业、企事单位、高校等机构单位。
使用场景:
BroadCast 监听系统广播或者程序内部自己发送的广播
EventBus 广播原理一样
LiveData 数据更新通知观察者
Adapter 中数据变化时,notifyDataSetChange
2、适配器模式(Adapter Pattern)
把一个类的接口转换为另一个类期待的接口类型,从而是接口不匹配的两个类兼容工作
ListView RecycleView使用适配器模式,通过创建适配器,让数据正确的供RecycleView使用
3、代理模式(Proxy Pattern)
为当前类提供一个代理类给其他类访问,以防止当前类直接暴露出去。
Activity的管理者是ActivityManager,但最终的管理者为ActivityManagerService(AMS),在Android7.0及以前版本中,ActivityManager通过调用ActivityManagerProxy进行一些操作,而ActivityManagerProxy会调用AMS,真正的工作是由AMS来完成的。()
4、工厂模式(Factory Pattern)
给外部提供一个统一创建特定对象的类,降低创建对象的复杂性。
Android中的BitmapFactory支持用不同的方式创建Bitmap对象。
5、单例模式(Singleton Pattern)
进程中只创建一个实例。Android8.0以上版本,IActivityManager和IActivityTaskManager实例都是单例,使用了系统的单例实现,不过看 源码 并没有使用所谓的什么高效的实现方式,直接把锁加到了获取实例的地方:
6、命令模式(Adapter Pattern)
把请求封装成一个对象,从而把不同的客户端参数化。
Handler使用了命令模式,客户端通过sendMessage()发送命令
7、装饰者模式(Decorator Pattern)
动态的给对象添加一些额外的职责
Context体系使用了装饰者,Context是抽象组件,ContextImpl是具体的组件,而ContextWrapper是装饰者,通过扩展ContextWrapper功能,实现Activity、Service等子类
8、责任链模式
一条请求沿着一条链挨个儿传递,直到有对象处理它为止。
Android中UI时间传递使用了责任链模式
OkHttp的拦截器也是使用责任链模式
9、建造者模式(Builder Pattern)
将一个复杂对象的创建和表示分离,使用相同的构建过程创建不同的对象。
AlertDialog使用了建造者模式。
装饰器模式:动态地给一个对象添加额外的职责。
背景:某果园在采摘完水果之后要将其打包,通过顾客反馈需要在原有的包装上做其他的处理,比如防伪、加固、加急。
测试结果
参考文章:
Android设计模式-装饰者模式
观察者模式是一个使用率非常高的模式,它最常用的地方是GUI系统、订阅——发布系统。因为这个模式的一个重要作用就是解耦,将被观察者和观察者解耦,使得它们之间的依赖性更小,甚至做到毫无依赖。以GUI系统来说,应用的UI具有易变性,尤其是前期随着业务的改变或者产品的需求修改,应用界面也会经常性变化,但是业务逻辑基本变化不大,此时,GUI系统需要一套机制来应对这种情况,使得UI层与具体的业务逻辑解耦,观察者模式此时就派上用场了。
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
我们以上课铃声响起,学生老师上课为例进行说明。
观察者模式主要的作用就是对象解耦,将观察者与被观察者完全隔离,只依赖于Observer和Observable抽象。例如,ListView就是运用了Adapter和观察者模式使得它的可扩展性、灵活性非常强,而耦合度却很低,这是设计模式在Android源码中优秀运用的典范。
1.单一职责 (一个class完成一件事)
2.开闭原则(继承)
3.依赖倒置原则(接口)
4.接口隔离原则(多个接口通讯)
4.里氏替换原则
5.迪米特原则(最小支持原则)
又称 FlyWeight,代表轻量级的意思,结构型设计模式。
享元模式是对象池的一种实现。类似于线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能。享元模式也是为了减少内存的使用,避免出现大量重复的创建销毁对象的场景。
享元模式用在一批相同或相似的对象上,这些对象有可以共享的内部状态和各自不同的外部状态。
享元模式中会有一个工厂,工厂维护着一个容器,容器以键值对的方式存储,键是对象的内部状态,也就是共享的部分,值就是对象本身。客户端从这个工厂获取对象,如果容器中存在这个对象就直接返回,不存在再创建新的对象并存入容器,避免了大量重复创建对象。
使用共享对象有效的支持大量的细粒度对象的复用。
系统中存在大量的 相似对象。
细粒度的对象都具备较接近的外部状态,且内部状态与环境无关,即对象没有特定身份。
需要 缓冲池 的场景。
例1. 过年回家买火车票,无数人在客户端上订票 (有多次购票、刷票的情况),即不断向服务端发送请求。
而每次查询,服务器必须做出回应,具体地,用户查询输入出发地和目的地,查询结构返回值只有一趟列车的车票。而数以万计的人有同样需求,即不间断请求数据,每次重新创建一个查询的车票结果,即造成大量重复对象创建、销毁,使得服务器压力加重。
享元模式正好适合解决该情形的问题,例如 A 到 B 地的车辆是有限的,车上铺位分硬卧、软卧和坐票三种,将这些可公用的对象缓存起来。用户查询时优先使用缓存,反之则重新创建。
我们知道 Java 中 String 是存在于常量池中,即一个 String 被定义之后它就被缓存到了常量池中,当其他地方使用同样的字符串,则直接使用缓存,而非创建。
享元模式的优缺点
优点 - 大幅度地降低内存中对象的数量。
缺点-1) 为了使对象可共享,需将一些状态外部化,使程序的逻辑复杂化
状态模式中的行为是由状态来决定的,不同的状态下有不同的行为。 状态模式和策略模式的结构几乎完全一样,但他们的目的、本质却完全不同。状态模式的行为是平行的、不可替换的,策略模式的行为是彼此独立、可相互替换的。 用一句话来表述,状态模式把对象的行为包装在不同的状态对象里,每一个状态对象都有一个共同的抽象状态基类。状态模式的意图是让一个对象在其内部改变的时候,其行为也随之改变。
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
下面我们就以电视遥控器为例来演示一下状态模式的实现。我们首先将电视的状态简单分为开机状态和关机状态,在开机状态下可以通过遥控器进行频道切换、调整音量等操作,但是,此时重复按开机键是无效的;而在关机状态下,频道切换、调整音量、关机都是无效的操作,只有按开机按钮时会生效。也就是说电视的内部状态决定了遥控器的行为。
上述实现中,我们抽象了一个TvState接口,该接口中有操作电视的所有函数,该接口有两个实现类,即开机状态(PowerOnState)和关机状态(PowerOffState)。开机状态下只有开机功能是无效的,也就是说在已经开机的时候用户再按开机键不会产生任何反应;而在关机状态下,只有开机功能是可用的,其他功能都不会生效。同一个操作,如调高音量的turnUp函数,在关机状态下无效,在开机状态下就会将电视的音量调高,也就是说电视的内部状态影响了电视遥控器的行为。状态模式将这些行为封装到状态类中,在进行操作时将这些功能转发给状态对象,不同的状态有不同的实现,这样就通过多态的形式去除了重复、杂乱的if-else语句,这也正是状态模式的精髓所在。
状态模式的关键点在于不同的状态下对于同一行为有不同的响应,这其实就是一个将if-else用多态来实现的一个具体示例。在if-else或者switch-case形式下根据不同的状态进行判断,如果是状态A那么执行方法A、状态B执行方法B,但这种实现使得逻辑耦合在一起,易于出错,通过状态模式能够很好地消除这类“丑陋”的逻辑处理,当然并不是任何出现if-else的地方都应该通过状态模式重构,模式的运用一定要考虑所处的情景以及你要解决的问题,只有符合特定的场景才建议使用对应的模式。