Design Pattrens
设计模式的六个原则
- 单一原则
每个类或方法都应该只被一个原因影响 - 开闭原则
类或方法应该对扩展开放, 对修改封闭 - 里氏替换原则
子类出现的地方一定可以被父类替换 - 接口隔离原则
接口的粒度要尽量的小 - 依赖倒置原则
抽象依赖抽象, 具体依赖抽象 - 迪米特原则
尽量无知, 朋友的朋友不是我的朋友
二十三种设计模式
共有三类23种设计模式
首先,简单工厂不是标准的GoF设计模式,但依然是常见的创建对象方式。
简单工厂模式:
关注点: 简单工厂模式关注于通过一个统一的工厂类创建不同的对象。
简单工厂通常没有子类。 但当从一个简单工厂中抽取出子类后, 它看上去就会更像经典的工厂方法模式了。
顺便提一句, 如果你将一个简单工厂声明为
abstract
类型, 它并不会神奇地变成抽象工厂模式。
e.g: ChoiceBarFactory
第一类是创建型:
工厂方法模式(虚拟构造函数、Factory Method)
关注点: 工厂方法模式侧重于单个对象的创建,每个具体工厂负责创建一个具体产品。
如果在基类及其扩展的子类中都有一个构建方法的话, 那它可能就是工厂方法。
e.g NumberFormat.getInstance()
抽象工厂模式(Abstract Factory)
关注点: 抽象工厂模式关注一组相关对象的创建,每个具体工厂负责创建一组相关的产品对象。
如果你的程序中并不涉及产品系列的话, 那就不需要抽象工厂。
再次重申, 许多人分不清抽象工厂模式和声明为
abstract
的简单工厂。 不要犯这个错误!生成器模式(构建者模式、Buider模式)
生成器关注于如何分步生成对象,通常支持方法链
e.g:- StringBuilder
- OkHttp的Request.Builder()
原型模式(克隆模式、ProtoType)
由被复制方自己提供clone() or copy()方法,故而调用方可不感知内部实现的情况下获取其备份
原型可以简单地通过
clone
或copy
等方法来识别。e.g:Java 的
Cloneable
(可克隆) 接口就是立即可用的原型模式。单例模式(Singleton)
单例模式让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。
e.g kotlin的object class,饿汉式单例模式是一种在类加载时就创建实例的单例模式。在 Kotlin 中,使用
object
关键字声明的对象在首次被访问时就会被创建,因此它是一种线程安全的单例实现方式。
第二类是结构型模式
适配器模式(Adapt)
使不兼容的对象能相互合作,接收一个对象的调用,将其转化为另一个对象可识别的格式和接口
e.g:- RecyclerView.Adapter
java.util.Arrays#asList()
代理模式 (Proxy)
关注将 重量级/远程/缓存 用代理的方式,为其提供占位符或替代品
代理与其服务对象遵循同一接口, 使得自己和服务对象可以互换
e.g:
binderProxy
Binder 和 BinderProxy 在 Android 中可以被视为代理模式的一种实现。
在 Android 中,Binder 是用于实现进程间通信(IPC,Inter-Process Communication)的机制。每个进程都有一个自己的 Binder 实例,用于处理本地进程内部的通信,以及与其他进程之间的通信。BinderProxy 则是用于在客户端进程中代理服务端进程中的 Binder 对象。
这种情况下,BinderProxy 可以被看作是一种代理,用于代表服务端进程中的 Binder 对象。客户端进程通过调用 BinderProxy 的方法,实际上是在发起跨进程调用,这个调用会被传送到服务端进程中的对应 Binder 对象。这个过程符合代理模式的基本思想,一个对象(BinderProxy)代理另一个对象(服务端进程中的 Binder 对象)执行一些操作。
总之,Binder 和 BinderProxy 在 Android 中可以被视为代理模式的一种应用,用于实现进程间通信。
Retrofit动态代理
享元模式(缓存模式)
利用如Integer缓存池的技术般,将可复用的对象通过共享的方式,让有限的内存可容纳更多的对象
e.g: 缓存了[-128, 127]的Integer类,外观模式
装饰模式
桥接模式
与适配器模式很像,区分于适配器模式的可能就是桥接模式更多用于前期设计,有预谋。
桥接模式通常会于开发前期进行设计, 使你能够将程序的各个部分独立开来以便开发。 另一方面, 适配器模式通常在已有程序中使用, 让相互不兼容的类能很好地合作。
e.g:如okhttp3.internal.http.BridgeInterceptor,涉及了header,请求和响应的转换、处理和传输,但并不是标准的桥接模式,桥接模式更多地涉及到将抽象和实现分离,以便它们可以独立地变化。
BridgeInterceptor
更多地关注在请求和响应之间进行数据的转换和协调,以便进行有效的网络通信。组合模式
第三类是行为模式
责任链模式
允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。
每个处理者都可处理或结束请求,由于每个处理者都持有下一个处理节点,故而请求将按顺序沿着链条传递。(可能会有处理者因为前面节点的提前返回而没有处理)
e.g:
- OkHttp中RealCall.getResponseWithInterceptorChain()即是一个责任链模式,每个节点都可都会追加对请求或响应的处理;
- Android的事件分发机制也是一种责任链,事件分发中,如果事件被处理了就会直接返回;
这些其实都是责任链,无论请求是否可被所有处理者处理过。
命令模式
将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。
迭代器模式
中介者模式
备忘录模式
观察者模式( 事件订阅者、监听者、Event-Subscriber、Listener、Observer)
发布者内部维护了一个订阅者对象列表
e.g:
- Animator.addListener()
- View.setOnClickListener
状态模式
e.g:kotlin的协程状态机
策略模式
有一种说法:(尤其针对策略模式)
一种针对不完善编程语言的蹩脚解决方案
通常当所选编程语言或技术缺少必要的抽象功能时, 人们才需要设计模式。 在这种情况下, 模式是一种可为语言提供更优功能的蹩脚解决方案。例如, 策略模式在绝大部分现代编程语言中可以简单地使用匿名 (lambda) 函数来实现。
e.g:
- Collections.sort():Collections.sort()最终调用的List(策略基类)的子类(ArrayList/Vector).sort;
- lambda
模板访问模式
访问者模式
解释器模式
Design Pattrens