代理模式
概念: Proxy Pattern,为其他对象提供一种代理, 以控制对这个对象的访问, 属于结构型模式。主要包含抽象主题角色, 真实主题角色,代理主题角色。
使用代理模式主要有两个目的: 保护目标对象和增强目标对象。
静态代理
静态代理只能通过手动完成代理动作。
动态代理
JDK动态代理原理:
- 获取被代理对象的引用, 获取所有接口,反射获取
- JDK动态代理类重新生成一个新的类, 新的类要实现被代理类实现的所有接口
- 动态生成Java代码
- 编译生成的Java代码
- 重新加载到JVM中运行
CGLIB动态代理采用了FastClass 原理:
- 为代理类和被代理类各生成一个类,这个类为代理类或被代理类的方法分配一个index
- index作为入参, FastClass可以直接定位要调用的方法,并进行调用,省去了反射调用,效率更高。
CGLIB和JDK动态代理对比:
- JDK动态代理实现了被代理对象的接口,CGLib代理继承了被代理对象
- JDK和CGLIB动态代理都在运行期生成字节码,JDK动态代理直接写Class字节码,CGLIB通过ASM写Class字节码, CGLIB代理实现更复杂,生成代理类效率低。
- JDK动态代理调用代理方法是通过反射机制调用, CGLib是通过FastClass机制调用的,CGLib代理的执行效率更高。
门面模式
概念: Facade Pattern, 也叫外观模式,提供了一个统一的接口,用来访问子系统的一群接口,特征是定义了一个高层接口,让子系统更容易使用,属于结构型模式。主要包含外观角色,子系统角色。主要在接口设计方面使用。
源码: JdbcUtils, Configuration
优点:
- 简化了调用过程
- 减少系统依赖,松散耦合
- 更好地划分访问层次, 提高安全性
- 遵循迪米特法则(最少知道原则)
装饰器模式
概念: Decorator Pattern, 包装模式(Wrapper Pattern)。 在不改变原有对象的基础上, 将功能附加到对象上,提供了比继承更有弹性的替代方案, 属于结构型模式。核心在于扩展, 可以透明且动态地扩展类的功能。包含抽象组件, 具体组件,抽象装饰器和具体装饰器。
源码: IO相关类,Cache
优点:
- 继承的有力补充,即插即用
- 通过不同装饰类以及这些装饰类的排列组合可以实现不同效果
- 遵守开闭原则。
享元模式
概念: Flyweight Pattern, 轻量级模式,对象池的一种实现。提供了减少对象数量从而改善应用所需的对象结构。共享细粒度对象,将多个对同一对象的访问集中起来,降低内存消耗,属于结构型模式。包含三个参与角色: 抽象享元角色, 具体享元角色和享元工厂。
享元模式把一个对象的状态分成内部状态和外部状态, 内部状态是不变的(不可变对象),外部状态(外蕴状态)是改变的,通过共享不变的部分,达到减少对象数量并节约内存的目的。
源码: String, Integer
组合模式
概念: Composite Pattern, Part-Whole模式。通过将单个对象和组合对象用相同的接口表示,使得客户对单个对象和组合对象的使用具有一致性,属于结构型模式。组合具有相同的生命周期,而聚合的生命周期不同。包含抽象根节点,树枝节点,叶子节点三个角色。
源码: HashMap, ArrayList
适配器模式
概念: Adapter Pattern, 变压器模式。将一个类的接口变成客户端所期望的另一种接口, 从而使原本因接口不匹配而导致无法在一起工作的两个类一起工作,属于结构型模式。包含目标角色,源角色,适配器三个角色。适配器分为类适配器, 对象适配器, 接口适配器三个形式。
类适配器是通过继承来实现适配器功能。
对象适配器是通过组合来实现适配器功能。
接口适配器解决接口方法过多。利用抽象类实现接口,空方法实现接口众多方法。
源码实现: AdvisorAdapter, HandlerAdapter
桥接模式
概念: Bridge Pattern, 桥梁模式,接口模式,柄体模式。将抽象部分与它的具体实现部分分离,使它们都可以独立地变化,属于结构型模式。包含抽象,修正抽象,实现,具体实现四个部分。
桥接模式主要目的是通过组合方式建立两个类的联系。
源码: JDBC