结构型模式 Structural Patterns

外观模式 Facade Pattern

  • 模式动机
    • 引入一个外观角色之后,用户只需要直接与外观角色交互,用户与子系统之间的复杂关系由外观角色统一处理,从而降低系统耦合度
  • 模式定义
    • 外观模式:外部与一个子系统的通信必须通过一个统一的外观对象进行
    • 为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
    • 又称为门面模式
    • 是一种对象结构型模式
  • 模式结构
    • Facade 外观角色
    • SubSystem 子系统角色
    • Client 客户类

截屏2026-06-07 18.27.41

  • 模式分析
    • 根据单一职责原则,将系统划分为若干个子系统有利于降低整个系统复杂性
    • 一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,引入外观对象就是一种实现方式,为子系统的访问提供了一个简单而单一的入口
    • 外观模式也是迪米特法则的体现:通过引入外观类,降低原有系统的复杂度,同时降低客户类与子系统类的耦合度
    • 外观类将客户端与子系统内部复杂性分隔开,客户端只需要与外观对象打交道
    • 外观模式的目的在于降低系统复杂程度,提高客户端使用的便捷性
  • 典型代码
public class Facade {
    private SubSystemA obj1 = new SubSystemA();
    private SubSystemB obj2 = new SubSystemB();
    private SubSystemC obj3 = new SubSystemC();

    public void method() {
        obj1.method();
        obj2.method();
        obj3.method();
    }
}
  • 模式实例
    • 电源总开关:一个总开关控制多盏灯、风扇、空调、电视机的启动和关闭
    • 文件加密:加密流程包括读取源文件、加密、保存加密文件,客户端通过统一的加密外观类完成整个流程
  • 模式优缺点
    • 优点
      • 对客户屏蔽子系统组件,减少客户处理的对象数量,使子系统使用起来更加容易
      • 实现了子系统与客户之间的松耦合关系,子系统组件变化一般不会影响客户端,只需要调整外观类
      • 降低大型软件系统中的编译依赖性并简化系统在不同平台之间的移植过程
      • 外观类只是提供统一入口,并不影响用户直接使用子系统类
    • 缺点
      • 不能很好地限制客户使用子系统类,如果限制太多又会降低可变性和灵活性
      • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端源代码,违背开闭原则
  • 模式适用环境
    • 当要为一个复杂子系统提供一个简单接口
    • 客户程序与多个子系统之间存在很大的依赖性,需要通过外观类解耦
    • 在层次化结构中,可以使用外观模式定义系统中每一层的入口,使层与层之间通过外观类建立联系,降低层间耦合度
  • 模式应用
    • JDBC 数据库操作可以封装为 JDBCFacade,统一提供 openexecuteUpdateexecuteQueryclose 等方法
    • Java EE 中的 Session Facade,客户端通过会话外观访问业务对象
  • 模式扩展
    • 一个系统可以有多个外观类
      • 通常情况下一个子系统只需要一个外观类,而且外观类常被设计为单例类
      • 但一个系统中也可以设计多个外观类,每个外观类负责与特定子系统交互,提供相应业务功能
    • 不要试图通过外观类为子系统增加新行为
      • 外观模式的用意是为子系统提供集中化、简化的沟通渠道
      • 新行为应该通过修改原有子系统类或增加新的子系统类实现,而不是通过继承外观类实现
    • 外观模式与迪米特法则
      • 外观类充当客户类与子系统类之间的“第三者”
      • 它把客户端涉及的子系统协作伙伴数量降到最低,是实现迪米特法则的一种常用重构方式
    • 抽象外观类的引入
      • 为解决外观模式违背开闭原则的问题,可以引入抽象外观类
      • 客户端针对抽象外观类编程
      • 新业务需求到来时,不修改原有外观类,而新增具体外观类,并通过配置文件更换外观对象

截屏2026-06-07 21.58.42

享元模式 Flyweight Pattern

  • 模式动机
    • 面向对象技术可以提高系统灵活性和可扩展性,但在很多情况下会导致类和对象数量增加
    • 当对象数量太多时,系统运行代价过高,可能带来性能下降
    • 享元模式通过共享技术实现相同或相似对象的重用
    • 享元模式的目的就是使用共享技术实现大量细粒度对象的复用
  • 内部状态与外部状态
    • 内部状态 Intrinsic State
      • 存储在享元对象内部,不会随环境改变而改变
      • 因此内部状态可以共享
    • 外部状态 Extrinsic State
      • 随环境改变而改变,不可以共享
      • 外部状态必须由客户端保存,并在需要使用时传入享元对象内部
    • 享元模式共享的是享元对象的内部状态,外部状态由外部环境设置
    • 因为能够共享的内部状态有限,所以享元对象一般设计为较小的细粒度对象
  • 模式定义
    • 享元模式:运用共享技术有效地支持大量细粒度对象的复用
    • 系统只使用少量对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用
    • 又称为轻量级模式
    • 对象结构型模式
  • 模式结构
    • Flyweight 抽象享元类
    • ConcreteFlyweight 具体享元类
    • UnsharedConcreteFlyweight 非共享具体享元类
    • FlyweightFactory 享元工厂类

截屏2026-06-07 22.05.37

  • 模式分析
    • 享元模式是一个考虑系统性能的设计模式
    • 使用享元模式可以节约内存空间,提高系统性能
    • 享元模式的核心在于享元工厂类
      • 享元工厂类维护一个享元池 Flyweight Pool
        • 用户需要对象时,先从享元池中获取
        • 如果享元池中存在,则直接返回已有对象
        • 如果享元池中不存在,则创建新的享元对象,放入享元池,再返回给用户
  • 典型代码
public class FlyweightFactory {
    private HashMap flyweights = new HashMap();

    public Flyweight getFlyweight(String key) {
        if (flyweights.containsKey(key)) {
            return (Flyweight) flyweights.get(key);
        } else {
            Flyweight fw = new ConcreteFlyweight();
            flyweights.put(key, fw);
            return fw;
        }
    }
}
public class Flyweight {
    private String intrinsicState;

    public Flyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    public void operation(String extrinsicState) {
        // 使用内部状态和外部状态完成操作
    }
}
  • 模式实例
    • 共享网络设备(无外部状态):多台终端计算机共享交换机、集线器等网络设备
    • 共享网络设备(有外部状态):网络设备可以共享,但每台终端使用的端口不同,端口作为外部状态传入
  • 模式优缺点
    • 优点
      • 极大减少内存中对象的数量
      • 相同对象或相似对象在内存中只保存一份
      • 外部状态相对独立,不影响内部状态,使享元对象可以在不同环境中共享
    • 缺点
      • 需要分离内部状态和外部状态,使系统更加复杂,程序逻辑复杂化
      • 为了使对象可以共享,需要将享元对象的状态外部化
      • 读取外部状态可能使运行时间变长
  • 模式适用环境
    • 一个系统有大量相同或相似对象,由于大量使用造成内存大量耗费
    • 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中
    • 享元模式需要维护享元池,只有在多次重复使用享元对象时才值得使用
  • 模式应用
    • 编辑器软件中多次出现相同图片时,只需创建一个图片对象,通过设置不同显示位置来重复使用
    • JDK 中的 String 类使用了享元思想,例如字符串常量池
  • 模式扩展
    • 单纯享元模式
      • 所有享元对象都可以共享
      • 所有抽象享元类的子类都可共享,不存在非共享具体享元类
    • 复合享元模式
      • 将一些单纯享元通过组合模式加以组合,形成复合享元对象
      • 复合享元对象本身不能共享,但可以分解成可以共享的单纯享元对象
    • 与其他模式联用
      • 享元工厂类中通常提供静态工厂方法返回享元对象,因此常与简单工厂模式联用
      • 系统中通常只有一个享元工厂,因此享元工厂类可以使用单例模式设计
      • 享元模式可以结合组合模式形成复合享元模式,统一对享元对象设置外部状态

代理模式 Proxy Pattern

  • 模式动机
    • 在某些情况下,客户端不想或者不能直接引用某个对象
    • 此时可以通过一个称为代理的第三者来实现间接引用
    • 代理对象可以在客户端和目标对象之间起到中介作用
    • 代理对象既可以去掉客户不能看到的内容和服务,也可以添加客户需要的额外服务
    • 引入代理对象来间接访问一个对象,就是代理模式的动机
  • 模式定义
    • 代理模式:给某一个对象提供一个代理,并由代理对象控制对原对象的引用
    • 代理模式英文叫做 Proxy 或 Surrogate
    • 对象结构型模式
  • 模式结构
    • Subject 抽象主题角色
    • Proxy 代理主题角色
    • RealSubject 真实主题角色
    • Client 客户类

截屏2026-06-07 23.23.48

  • 模式分析
    • 抽象主题角色声明真实主题和代理主题的共同接口
    • 代理主题角色内部包含对真实主题的引用,从而可以在任何时候操作真实主题对象
    • 真实主题角色定义代理角色所代表的真实对象,在真实主题角色中实现真正的业务操作
    • 客户端通过代理主题角色间接调用真实主题角色中的方法
    • 代理类一般会在调用真实主题方法之前或之后执行额外操作
  • 典型代码
public class Proxy implements Subject {
    private RealSubject realSubject = new RealSubject();

    public void preRequest() {
        // 调用真实对象之前的操作
    }

    public void request() {
        preRequest();
        realSubject.request();
        postRequest();
    }

    public void postRequest() {
        // 调用真实对象之后的操作
    }
}
  • 模式实例
    • 论坛权限控制代理
      • 已注册用户和游客权限不同
      • 使用保护代理控制对真实权限对象的访问,为不同用户提供不同级别权限
    • 数学运算代理
      • 远程对象实现加减乘除等运算
      • 本地通过代理调用远程对象方法,模拟远程代理
  • 模式优缺点
    • 优点
      • 能够协调调用者和被调用者,在一定程度上降低系统耦合度
      • 远程代理使客户端可以访问远程机器上的对象
      • 虚拟代理通过使用小对象代表大对象,减少系统资源消耗,优化系统并提高运行速度
      • 保护代理可以控制对真实对象的使用权限
    • 缺点
      • 在客户端和真实主题之间增加代理对象,有些类型的代理模式可能造成请求处理速度变慢
      • 实现代理模式需要额外工作,有些代理模式实现非常复杂
  • 模式适用环境 / 常见类型
    • 远程代理 Remote Proxy
      • 为位于不同地址空间的对象提供一个本地代理对象
      • 又称为大使 Ambassador
    • 虚拟代理 Virtual Proxy
      • 如果需要创建资源消耗较大的对象,可以先创建一个消耗较小的对象来表示
      • 真实对象只在需要时才真正创建
    • Copy-on-Write 代理
      • 虚拟代理的一种
      • 将复制或克隆操作延迟到客户端真正需要时才执行
    • 保护代理 Protect / Access Proxy
      • 控制对一个对象的访问,可以给不同用户提供不同级别的使用权限
    • 缓冲代理 Cache Proxy
      • 为某个目标操作结果提供临时存储空间,使多个客户端可以共享结果
    • 防火墙代理 Firewall Proxy
      • 保护目标对象,不让恶意用户接近
    • 智能引用代理 Smart Reference Proxy
      • 当一个对象被引用时,提供额外操作,例如记录对象被调用次数
  • 模式应用
    • Java RMI 远程方法调用
    • EJB、Web Service 等分布式技术
    • EJB 中远程服务器中的企业级 Bean 在本地有桩代理,客户端通过桩调用远程对象方法,而不需要直接与远程对象交互
  • 模式扩展
    • 远程代理
      • 可以隐藏网络通信细节,使客户端不必考虑网络存在
      • 客户端可以像使用本地对象一样使用远程业务对象
    • 虚拟代理
      • 当对象加载非常耗费资源时,先用代理对象代替真实对象初始化
      • 可以节省内存并加快系统启动速度
      • 常见例子是大图浏览:先加载小图片,后台加载大图,需要查看时再显示真实大图

英文补充 English Supplement

Facade Pattern 外观模式

英文定义:

Provide a unified interface to a set of interfaces in a subsystem.
Facade defines a higher-level interface that makes the subsystem easier to use.

中文意思:

为子系统中的一组接口提供一个统一接口。外观定义了一个更高层的接口,使子系统更容易使用。

别名:

Facade
门面模式

核心术语:

English 中文 说明
Facade 外观角色 客户端直接调用的统一入口
Subsystem 子系统角色 实现具体功能的一组类或对象
Client 客户端 通过 Facade 使用子系统功能
unified interface 统一接口 对复杂子系统提供一致入口
higher-level interface 高层接口 简化客户端调用的接口

关键句:

Facade simplifies access to a subsystem but does not prevent direct access to subsystem classes.
外观模式简化对子系统的访问,但不禁止客户端直接访问子系统类。

考试表达:

  • Facade Pattern reduces coupling between clients and subsystems.
  • Facade Pattern is an application of the Law of Demeter.
  • Facade provides a simple entry point to a complex subsystem.
  • Without an abstract facade, adding new subsystems may violate the Open-Closed Principle.

Flyweight Pattern 享元模式

英文定义:

Use sharing to support large numbers of fine-grained objects efficiently.

中文意思:

运用共享技术有效地支持大量细粒度对象。

别名:

Lightweight Pattern
轻量级模式

核心术语:

English 中文 说明
Flyweight 抽象享元 声明接受外部状态的接口
ConcreteFlyweight 具体享元 可共享的享元对象
UnsharedConcreteFlyweight 非共享具体享元 不可共享的享元对象
FlyweightFactory 享元工厂 创建并管理享元池
Flyweight Pool 享元池 保存可共享对象
Intrinsic State 内部状态 存在对象内部,可以共享
Extrinsic State 外部状态 由外部传入,不可共享

关键句:

Flyweight shares intrinsic state and externalizes extrinsic state.
享元模式共享内部状态,并将外部状态外部化。

考试表达:

  • Flyweight Pattern is useful when a system has many similar objects.
  • It reduces memory usage by sharing objects.
  • It requires separating intrinsic state from extrinsic state.
  • It may increase complexity and runtime cost for passing external state.

Proxy Pattern 代理模式

英文定义:

Provide a surrogate or placeholder for another object to control access to it.

中文意思:

为另一个对象提供一种代理或占位符,以控制对这个对象的访问。

别名:

Surrogate
替身 / 代理

核心术语:

English 中文 说明
Subject 抽象主题 声明真实主题和代理主题的共同接口
Proxy 代理主题 持有 RealSubject 引用,控制访问
RealSubject 真实主题 真正执行业务逻辑的对象
surrogate 代理 / 替身 替真实对象接受请求
placeholder 占位符 在真实对象创建或访问前代表它
control access 控制访问 代理模式的核心目的

关键句:

Proxy controls access to an object, while Decorator adds responsibilities to an object.
代理模式控制对象访问,装饰模式给对象增加职责。

常见代理类型:

Type 中文 作用
Remote Proxy 远程代理 为远程对象提供本地代表
Virtual Proxy 虚拟代理 延迟创建昂贵对象
Protection Proxy 保护代理 控制访问权限
Cache Proxy 缓冲代理 缓存目标操作结果
Firewall Proxy 防火墙代理 阻止恶意访问
Smart Reference Proxy 智能引用代理 对对象引用增加额外操作

考试表达:

  • Proxy and RealSubject implement the same Subject interface.
  • The client talks to Proxy instead of RealSubject directly.
  • Proxy may perform pre-processing and post-processing around the real request.
  • Proxy may improve security or resource usage, but it may also slow down request processing.

Facade vs Proxy vs Decorator

Pattern 中文 核心目的 结构特点
Facade 外观模式 简化对子系统的访问 一个外观对象封装多个子系统对象
Proxy 代理模式 控制对某个对象的访问 代理和真实对象实现同一接口
Decorator 装饰模式 动态增加对象职责 装饰者和被装饰者实现同一接口,装饰者持有构件

一句话区分:

Facade simplifies, Proxy controls, Decorator extends.
外观负责简化,代理负责控制,装饰负责扩展。