23种常见设计模式
设计模式主要都是面向对象的。
设计模式分为三大类:
1、创建型设计模式
2、结构型设计模式
3、行为型设计模式
设计模式六大基本原则
六大基本原则: 单一职责原则、开放封闭原则(修改关闭、扩展开放)、依赖倒转原则(高层不应该依赖低层模块,两个应该都依赖抽象;抽象不应该依赖细节,细节应该依赖抽象)、里斯代换原则(子类型必须能够完全替换掉它们的父类型、迪米特法则:如果2个类不必直接通信,那么这2个类就不应该发生直接的相互引用,我们应该降低耦合性,通过第三方接口的形式去实现,还有一个合成聚合复用原则(这个后续补充)
创建型设计模式
简单工厂: 不符合开闭原则,每次扩展都需要修改工厂类。
工厂方法模式: 1个抽象工厂类,1个抽象产品类,具体的工厂类只生产具体的产品。我的观点里,工厂方法跟简单工厂没有优劣之分,只有合适的场景。之前的简单工厂的优点是工厂类中包含了逻辑判断,然后根据客户端的选择动态实例化相关的类。但是呢,如果新增逻辑判断 那就需要改到简单工厂类的逻辑,就违背了开闭原则,而采用工厂方法的话 我们只需要动态的添加一个工厂类跟一个产品类即可。当然了,这样就导致类很容易增加,而且把之前的逻辑判断移到客户了。
抽象工厂方法: 提供一个创建一系列或者相关依赖对象的接口,而无需指定他们具体的类。就是抽象工厂可以同时生产多个不同类型的产品,这样相对一个工厂类只能生产一种类型的产品扩展性要强,抽象工厂针对具体产品的修改或者具体工厂类的修改很方便,但是对于工厂新增一个产品的话 那么改动的地方非常多既要新增一种产品类型 同时多个工厂类也要随着改动,因此我们采用反射+抽象工厂去实现。
建造者模式: 将一个复杂的对象的构建过程跟它的表示分离,使得同样的过程可以创建不同的表示。
原型模式: 一个原型的实例对象 通过拷贝的形式 生成一个新的对象,而且不需要关心任何创建对象的细节。而拷贝呢、分为深拷贝跟浅拷贝。
浅拷贝: 如果对象里的字段是引用类型,那么原始对象跟复制后的对象这个字段引用的是同一个对象。
深拷贝: 如果对象的字段是引用类型,那么原始对象跟复制后的对象 这个字段引用的是不同的对象(相当于是新生成一个对象)。
单例模式: 保证一个类在进程中仅有一个实例,并且只提供一个访问它的全局访问点。主要是注意构造函数得是private 不然没有意义,其次要使用双重锁定,因为在多线程情况下我们需要用锁,但是如果每次都使用锁呢就又耗费性能,所以我们使用双重锁定(先判断实例是否为空,为空就开始锁,再次判断实例是否为空)
之间的比较: 抽象工厂可以解决多个产品创建问题但是太过臃肿,单例太过单一,原型模式呢可以做到数据的复制,建造者呢可以把创建隐藏,做到了高内聚,但是相同建造过程的对象不多,所以从new的角度来说,工厂方法呢是最好的,毕竟把工厂分类了。
结构型设计模式
适配器模式: 将原本由于接口不兼容而不能一起工作的类可以一起工作,也就是将一个类的接口转换成客户希望的另外一个接口。
桥接模式: 我个人基本上没有使用过,所以这个模式暂时放弃研究。是将抽象部分跟实现部分进行分离,使他们都可独立的发生变化。
组合模式: 有点像树型结构,我个人不太能接受、也不太能理解,先放一边,我们可以参考我们的view体系。
使得用户对单个对象和组合对象的使用具有一致性。
装饰模式: 动态的给一个对象添加一些额外职责,有效的把类的核心功能跟装饰功能区分开了。跟建造者不同的是,装饰模式对象的创建是有先后顺序的,而建造者没有。
外观模式: 当我们存在很多个子系统的时候,如果客户直接基于自己的需求去使用相应的子系统,那么客户的使用成本非常大 他需要了解不同系统的差异跟区别。在这个情况下,我们采用新增一个外观类,这个类去负责处理具体使用子系统的方法,而我们客户只需要直接调用外观类里面的方法就可以了,降低了使用成本。
享元模式: 就是运用共享技术有效的支持大量细粒度的对象。其实我们日常中接触的非常多,但是感觉都会忽略这个设计模式。使用较少的共享对象取代很多组对象
代理模式: 通过代理类跟真实类实现同一个接口而实现。为其他对象提供一种代理以控制对这个对象的访问。代理中也有动态代理跟静态代理。 小结: 结构型设计模式,有些我现在的确接触的不多、也没多少的理解 。这块暂时放置,回头需要了就一点点补充。
行为型设计模式
观察者模式: 定义了1对多的依赖关系,让多个观察者同时监听一个主题对象,这个主题在发生变化时,会通知所有的观察者,使他们能够自动的更新自己。
模板方法: 当我们实现一个多步骤的过程,针对不同的现象过程基本上是一致的,只是存在一点点细微的差别。为了过程的可复用,我们会采用模板方法。模板方法就是我们定义一个抽象类。里面包含一个具体方法(是一个顶层逻辑的骨架)跟多个步骤的抽象方,我们就将具体细节差异的实现放到子类中进行。这样就可以保证主流程框架不变的情况下,针对具体用户的细微差别就可以通过特定的实现。 其实个人感觉有点像结构型模式。
命令模式: 对于我来说 基本上没有使用场景 所以不太能理解到精华,先放一边,以后有使用场景再补充。
状态模式: 顾名思义,就是这个过程存在很多种状态,我们通常采用if else这种形式 那这样 我们的方法代码逻辑会非常长,那么这个大的分支判断的改动或者扩展就变得尤为谨慎,基于此,我们将这些if else根据实际场景分为不同的状态进行切割开来 每个状态是一个实现类,每个状态内部如果不满足 就可以进行else状态的判断,这样就容易扩展一些,但是这样呢 类变多了 结构也清晰了。
责任链模式: 使得多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象能处理他为止,类似我们最常用的okhttp的拦截器。
下面是第二组行为型设计模式
解释器模式: 字面意思就是解释,暂时不分析这个设计模式,用到了再看。
中介者模式: 相对来说比较会理解,但是我在实际项目中接触的很少,中介模式就是用一个中介对象封装一系列的对象交互。中介者使各个对象不需要显示的相互调用,从而使得耦合松散。
访问者模式: 也是先放一边,遇到了再看
策略模式: 简单工厂跟策略模式的区别 简单工厂 我们需要认识工厂类及相应的产品的父类 而策略模式 我们只需要认识策略类其产品的父类 我们融合到策略类中了,耦合更加低了
迭代器模式: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。我觉得就是一个遍历而已 无非遍历的逻辑写法丢到一个迭代器类里而已。或者说存在多种遍历方式也可以使用迭代器模式。
备忘录模式: 在不破坏封装性的情况下,在对象之外去保存这个对象的状态,这样就可以将对象恢复到原来的状态 比如我们常用的reset()方法 commit方法等。