2026年7月11日 · 4 分钟阅读

Java 结构型设计模式:适配器、桥接、装饰者、组合、外观、享元与代理

梳理结构型设计模式如何组织对象关系,以及它们在 Java 项目中的典型使用场景。

结构型模式关注对象之间如何组合。

创建型模式解决“对象怎么来”,结构型模式解决“对象怎么协作成更大的结构”。它通常不改变核心对象本身,而是通过包装、组合、代理、共享等方式增强系统能力。

结构型设计模式

适配器模式

适配器模式用于解决接口不兼容问题。

例如系统需要统一的支付接口,但第三方支付 SDK 的接口和系统定义不一致,就可以使用适配器。

public interface PaymentClient {
    void pay(String orderNo, int amount);
}

public class ThirdPartyPaySdk {
    public void submitPay(String id, int cents) {
        System.out.println("pay " + id);
    }
}

public class ThirdPartyPayAdapter implements PaymentClient {
    private final ThirdPartyPaySdk sdk;

    public ThirdPartyPayAdapter(ThirdPartyPaySdk sdk) {
        this.sdk = sdk;
    }

    public void pay(String orderNo, int amount) {
        sdk.submitPay(orderNo, amount);
    }
}

适配器适合对接遗留系统、第三方 SDK、旧接口升级。

桥接模式

桥接模式用于把抽象和实现分离,让两个维度可以独立变化。

例如消息发送有两个变化维度:

  • 消息类型:普通消息、告警消息。
  • 发送渠道:短信、邮件、企业微信。

如果使用继承组合,会出现大量类。桥接模式可以把渠道抽象出来。

public interface Sender {
    void send(String content);
}

public abstract class Message {
    protected final Sender sender;

    protected Message(Sender sender) {
        this.sender = sender;
    }

    public abstract void notify(String content);
}

桥接模式适合多个维度同时变化的场景。

装饰者模式

装饰者模式用于在不修改原对象的情况下,动态增强功能。

典型例子是 Java IO:

InputStream input = new BufferedInputStream(new FileInputStream("a.txt"));

BufferedInputStream 并不改变 FileInputStream,而是在外层增加缓冲能力。

业务中也可以用装饰者实现权限增强、日志增强、缓存增强。

组合模式

组合模式用于处理树形结构,让单个对象和组合对象具有一致接口。

典型场景:

  • 组织架构。
  • 文件目录。
  • 菜单树。
  • 商品分类。
public interface MenuNode {
    void print();
}

public class MenuItem implements MenuNode {
    public void print() {
        System.out.println("item");
    }
}

public class MenuGroup implements MenuNode {
    private final List<MenuNode> children = new ArrayList<>();

    public void add(MenuNode node) {
        children.add(node);
    }

    public void print() {
        children.forEach(MenuNode::print);
    }
}

组合模式的关键是统一叶子节点和容器节点的处理方式。

外观模式

外观模式为复杂子系统提供一个统一入口。

例如下单流程可能涉及库存、优惠券、支付、物流。调用方不应该直接编排所有子系统,可以通过一个外观服务封装流程。

public class OrderFacade {
    public void createOrder() {
        // check stock
        // lock coupon
        // create payment
        // notify logistics
    }
}

外观模式适合降低调用方复杂度,但不要把所有业务都塞进一个巨大的 Facade。

享元模式

享元模式通过共享对象减少内存占用。

适合大量细粒度对象,并且这些对象内部状态可复用的场景。

常见例子:

  • 字符串常量池。
  • 数据库连接池。
  • 缓存对象。
  • 棋子、图标、样式等可复用对象。

使用享元模式时,要区分内部状态和外部状态。内部状态可以共享,外部状态由调用方传入。

代理模式

代理模式通过代理对象控制对目标对象的访问。

常见用途:

  • 权限控制。
  • 日志记录。
  • 延迟加载。
  • 远程调用。
  • 事务增强。

静态代理示例:

public interface UserService {
    void updateUser();
}

public class UserServiceImpl implements UserService {
    public void updateUser() {
        System.out.println("update user");
    }
}

public class UserServiceProxy implements UserService {
    private final UserService target;

    public UserServiceProxy(UserService target) {
        this.target = target;
    }

    public void updateUser() {
        System.out.println("check permission");
        target.updateUser();
    }
}

Spring AOP 中大量使用代理思想,用于事务、日志、权限等横切能力。

结构型模式选择建议

场景推荐模式
新旧接口不兼容适配器
多个维度独立变化桥接
动态增强对象能力装饰者
树形结构统一处理组合
隐藏复杂子系统外观
大量对象可共享享元
控制访问或横切增强代理

小结

结构型模式的重点是组织对象关系。

当系统中出现接口不兼容、对象组合复杂、横切增强、树形结构、访问控制等问题时,结构型模式通常能让代码边界更清晰。