设计模式是无数码农前人在实际的生产项目中经过不断的踩坑、爬坑、修坑的经历总结出来的经验教训, 经过抽象之后表达成的概念。能够帮助后来的设计者避免重复同样的错误或者弯路。 你觉得不好理解,实际上并不是你看不懂,而是你不明白为何要如此“故弄玄虚"。这个很好明白,等你真 正经历大型项目开发、迭代、重构、甚至重写之后,你就会赞同这些能写出设计模式的人,是多么的高瞻 远瞩,多么的有智慧。 一言以蔽之,设计模式的本质就是一句话:将软件中变化的部分和不变的部分分开。
全套视频讲解地址:https://www.bilibili.com/video/av57936239?p=1
设计模式的六大原则
- 开闭原则:模块应尽量在不修改原代码(闭)的情况下进行扩展(开)。即在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
- 里氏代换原则:如果调用的是父类的话,那么换成子类也完全可以运行。 派生类能够在基类的基础上增加新的行为。只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
- 依赖倒置原则:1、高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。2、抽象不应该依赖于具体实现,具体实现应该依赖于抽象。要求对抽象/接口进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
- 接口隔离原则:每一个接口应该是一种角色,不干不该干的事,该干的事都要干。降低类之间的耦合度。
- 合成复用原则:要尽量使用组合/ 聚合,尽量不要使用继承。只有“Is - A” 关系才符合继承关系,“Has- A” 关系应当使用聚合来描述。
- 最少知识原则:一个对象应对其它对象有尽可能少的了解。即一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
创建型模式( Creational Patterns )
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用新的运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
- 单例模式 (Singleton Pattern):保证一个类仅有一个实例
- 饿汉式
- 懒汉式
- 双重加锁懒汉式
- 静态式
- 枚举式
- 原型模式 (Prototype Pattern):通过拷贝原型创建新的对象
- 抽象工厂模式 (Abstract Factory Pattern):不同条件下创建不同实例
- 抽象工厂是出现两个或者多个简单工厂时,创建超级工厂,通过超级工厂获取简单工厂,再通过简单工厂获取对象实现功能,也可以参考https://www.runoob.com/design-pattern/abstract-factory-pattern.html
- //获取形状工厂 AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
- //获取形状为 Circle 的对象 Shape shape1 = shapeFactory.getShape("CIRCLE");
- //调用 Circle 的 draw 方法 shape1.draw();
- 建造者模式 (Builder Pattern):将一个复杂的构建过程与其具表示细节相分离,使得同样的构建过程可以创建不同的表示
-
AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle("自定义弹框测试").create().show();
- 创建AlertDialog的内部类建造者Builder的对象builder,然后给builder中的参数AlertParams赋值,然后在调用create的时候生成新建dialog对象并把AlertParams参数给dialog。
-
- 工厂模式(Factory Pattern):不同条件下创建不同实例
- 简单工厂模式,用于生产相同类型的对象,参考多个监听ListenerFactory的实现
结构型模式( Structural Patterns )
这些设计模式关注类和对象的组合。
- 组合模式 (Composite Pattern):用户对单个对象和组合对象的使用具有一致性的统一接口
- 装饰器模式 (Decorator Pattern):保持接口,增强性能:修饰类继承被修饰对象的抽象父类,依赖被修饰对象的实例(被修饰对象依赖注入),以实现接口扩展
- 外观模式 (Facade Pattern):在客户端和复杂系统之间再加一层,这一次将调用顺序、依赖关系等处理好。即封装底层实现,隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的高层接口
- 桥接模式 (Bridge Pattern):两个维度独立变化,依赖方式实现抽象与实现分离:需要一个作为桥接的接口/抽象类,多个角度的实现类依赖注入到抽象类,使它们在抽象层建立一个关联关系
- 享元模式 (Flyweight Pattern):享元工厂类控制;HashMap实现缓冲池重用现有的同类对象,如果未找到匹配的对象,则创建新对象
- 适配器模式 (Adapter Pattern):使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
- listView adapter
- recycleView adapter
- 代理模式 (Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问:增加中间层(代理层),代理类与底层实现类实现共同接口,并创建底层实现类对象(底层实现类对象依赖注入代理类),以便向外界提供功能接口
行为型模式( Behavioral Patterns )
这些设计模式特别关注对象之间的通信。
- 访问者模式(Visitor Pattern):将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
- 中介者模式(Mediator Pattern):对象与对象之间存在大量的关联关系,将对象之间的通信关联关系封装到一个中介类中单独处理,从而使其耦合松散,可以独立地改变它们之间的交互
- 备忘录模式(Memento Pattern):通过一个备忘录类专门存储对象状态。客户通过备忘录管理类管理备忘录类。
- 模板模式(Template Pattern):将这些通用算法抽象出来,在一个抽象类中公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行
- 观察者模式(Observer Pattern):指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式
- boserver观察者模式,美团外卖通过极光推送的订单信息,在被观察者中刷新,在订单列表界面以及订单详情界面分别注册观察者从而观察到变化进行更新
- 状态模式(State Pattern):状态对象依赖注入到context对象,context对象根据它的状态改变而改变它的相关行为(可通过调用内部的状态对象实现相应的具体行为)
- 状态机,录屏帝应用中有明显的状态切换,采用状态模式,有idle状态、init状态、start状态、recording状态、pause状态、stop状态、release状态、error状态
- 解释器模式(Interpreter Pattern):给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子
- 职责链模式(Chain of Responsibility Pattern):拦截的类都实现统一接口,每个接收者都包含对下一个接收者的引用。将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。视频讲解地址:https://www.bilibili.com/video/av57936239?p=145
- 职责链模式场景如录屏帝中,开启前的条件检查,危险权限判断及弹框、自定义声明弹框、mediaprojection权限弹框判断,这些统一继承一个接口,一个接收者包含下一个接受者的引用,当前的条件允许时,进入下一个接受者的处理,知道所有场景都同意时,职责全部满足,流程走完进行下一个流程
- 迭代器模式(Iterator Pattern):集合中含有迭代器:分离了集合对象的遍历行为,抽象出一个迭代器类来负责,无须暴露该对象的内部表示
- 策略模式(Strategy Pattern):策略对象依赖注入到context对象,context对象根据它的策略改变而改变它的相关行为(可通过调用内部的策略对象实现相应的具体策略行为)
- 命令模式(Command Pattern):将"行为请求者"与"行为实现者"解耦:调用者依赖命令,命令依赖接收者,调用者Invoker→命令Command→接收者Receiver
- 空对象模式(Null Object Pattern):创建一个未对该类做任何实现的空对象类,该空对象类将无缝地使用在需要检查空值的地方。不要为了屏蔽null而使用空对象,应保持用null,远比用非null的值来替代“无值”要好。(慎用)
- 过滤器模式 (Filter、Criteria Pattern):使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来
其实还有两类:并发型模式和线程池模式。用一个图片来整体描述一下: