结构型设计模式

128 阅读4分钟

代理模式

概念: 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