单例模式
- 饿汉式(静态常量)
- 饿汉式(静态代码块)
- 懒汉式(线程不安全)
- 懒汉式(线程安全,同步方法)
- 懒汉式(安全,同步代码块)
- 双重检查
- 静态内部类
- 枚举
注意事项和细节
- 一个类只有一个对象,节省了系统资源
- 需要频繁创建和销毁的对象、创建时消耗过多或消耗资源过多但又又经常用到的对象(工具类,数据源,session工厂)
案例:jdk中的Runtime就是单例模式
工厂模式
- 简单工厂模式:定义一个创建对象的类(工厂),让这个类封装实例化对象的行为(工厂创建对象实例)。
- 抽象工厂模式:定义了一个interface用于创建相关或者有依赖的对象簇;将工厂模式抽象成两层(抽象工厂和具体的实现类)我们可以根据需求创建对应的工厂子类
- 意义:将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的解耦,提高项目的扩展和维护性
案例:jdk中calender
原型模式
- 浅克隆:实现cloneable接口,直接调用父类Object的clone方法;对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递(拷贝一份新的);对于引用类型的成员变量,只是将引用值(内存地址)复制一份给新的对象;案例: Spring中原型bean的创建
- 深克隆:实现cloneable接口,对原型中的每一个引用对象都clone
建造者模式
- 源码分析:StringBuilder
- 注意事项和细节:客户端不必知道产品本身与产品创建的过程,使相同的创建过程可以创建不同的产品对象;用户使用不同的具体建造者就可以得到不同的产品对象;可以更加精细控制产品创建过程。
适配器模式
- 将某个类的接口转换成客户端期望的另一个接口表示
- 类适配器;对象适配器;接口适配器
- 案例:springMVC中HandlerAdapter
桥接模式
- 将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变,有助于系统进行分层设计,结构化系统
- 对于系统高层来说,只需要完成抽象部分和实现接口,其他的扩展交给具体业务来完成
- 需要正确识别出系统中两个独立变化的维度,因此使用范围有局限性
- 案例分析:JDBC
装饰者模式
- 动态的将新功能附加到对象上,在对象扩展方面,比继承更具有弹性
- 源码分析:IO流(InputStream。。。FileInputStream)
组合模式
- 将对象组合成树状结构以表示整体部分的层次关系
- 组合能让客户以一致性的方式处理个别对象以及组合对像
- 当我们要处理的对象可以组成一颗树形结构,并且想对树上的节点进行处理,就可以用组合模式
- 如果节点和叶子差异很大的情况下,不适合使用组合模式
- 源码分析:HashMap
外观模式
- 创建各个子系统的对象,并直接调用子系统相关方法会造成混乱,不利于对子系统的维护
- 定义一个高层接口,给子系统中的接口提供一个一致的界面,来屏蔽内部子系统的细节,使得调用只需要和这个高层接口对接
- 案例:MyBatis中的Configuration去创建MetaObject对象使用到外观模式
享元模式
- 运用共享技术有效的支持大量细粒度的对象
- 常用于系统底层的开发,解决系统的性能问题(数据库连接)
- 能解决重复对象的内存浪费问题(池技术)
- 案例:Integer.valueOf()
代理模式
- 为一个对象提供一个替身,以控制对这个对象的访问。可以再目标对象实现的基础上,增强额外的功能操作
- 被代理的对象可以是远程对象,创建开销大的对象或安全控制的对象
- 主要有三种,静态代理,动态代理,cglib代理
命令模式
- 命令模式使得请求发送者和请求接受者消除彼此的耦合,让对象之间调用变得更加灵活,实现解耦
- 案例分析:JdbcTemplete
访问者模式
- 主要将数据结构与数据操作分离,解决数据结构和操作耦合性问题
- 原理:在被访问的类里面加一个对外提供接待访问者的接口
- 应用场景:需要对一个对象结构中的对象进行很多不同的操作(操作互不相关),同时需要避免让这些操作污染对象的类
迭代器模式
- 案例分析:ArrayList
- 常用方式:在聚集类中创建一个私有内部类实现Iterator接口,并通过方法返回这个迭代器实现对象
- 提供了一个统一的方法遍历对象,客户不再考虑聚合的类型,使用统一的方法就可以遍历对象
- 隐藏了聚类的内部结构,只能获取迭代器才能遍历
- 缺点,每个聚类都需要一个迭代器
观察者模式
- 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式
- 案例:Observable
中介者模式
- 用一个中介对象封装一系列的对象交互,中介者使各个对象不需要显示的相互引用
- 缺点:中介类承担较多的责任,一旦出现问题,整个系统就会出现影响
- 案例分析:MVC中controller是model和view的中介
备忘录模式
- 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这样一个状态(以后可以将该对象回复)
- 如果类的成员较多,会占用较大的资源,每次保存消耗一定的内存(可与原型模式搭配)
- 引用场景ctrl+z 游戏存档 浏览器中的后退
解释器模式
- 指定一个语言表达式,定义他的文法,并定义一个解释器,使用该解释器来解释语言中的句子
- 应用场景:编译器,运算表达式,正则表达式等
- 案例分析:Spring框架中SpelExpressionParser
状态模式
- 解决对象在多种状态转换时,需要对外输出不同的行为的问题,状态和行为是一一对应的,状态之间可以相互转换
- 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类
- 缺点:会产生很多类,每个状态都要对应一个类,当状态过多会增加维护难度。
- 应用场景:当一个事件或者对象有很多状态,状态之间会相互转换,对不同的状态要求不同的行为
策略模式
- 源码分析:Arrays.sort()
- 核心思想:多用组合聚合,少用继承,用行为类组合而不是继承
- 缺点,每有一个策略就会增加一个类,策略过多就会导致类数目过大
责任链模式
- 源码分析:SpringMVC中的HandlerExecutionChain(拦截器的pre post after)
- 应用场景:有多个对象处理同一个请求时(拦截器, 多级请求, 审批流程)
- 缺点:性能会受到影响,特别是责任链比较长的时候,需要控制节点数量