设计模式中,Facade模式(外观模式)的原理介绍,完整示例及Adapter对比,一文详解!

Facade模式(外观模式)完整示例及Adapter对比

🎯 场景:注册一家公司

注册公司需要走三个子系统:

  • 工商局 → 申请营业执照
  • 银行 → 开设公司账户
  • 税务局 → 申请纳税号

如果让用户自己对接三个部门,流程复杂,接口难记。于是我们引入 Facade(外观),由它来统一处理,客户只用调用一个方法即可。


🔹 代码实现

1. 公司实体

public class Company {
    private String id;
    private String name;
    private String bankAccount;
    private String taxCode;

    public Company(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setBankAccount(String bankAccount) {
        this.bankAccount = bankAccount;
    }

    public void setTaxCode(String taxCode) {
        this.taxCode = taxCode;
    }

    @Override
    public String toString() {
        return "Company{id='" + id + "', name='" + name + "', bankAccount='" + bankAccount + "', taxCode='" + taxCode + "'}";
    }
}

2. 各子系统接口

// 工商局:负责注册公司
public class AdminOfIndustry {
    public Company register(String name) {
        System.out.println("工商局:注册公司 -> " + name);
        return new Company("ID-" + System.currentTimeMillis(), name);
    }
}

// 银行:负责开设公司账户
public class Bank {
    public String openAccount(String companyId) {
        System.out.println("银行:为公司ID " + companyId + " 开设账户");
        return "BANK-" + companyId;
    }
}

// 税务局:负责分配纳税号
public class Taxation {
    public String applyTaxCode(String companyId) {
        System.out.println("税务局:为公司ID " + companyId + " 分配纳税号");
        return "TAX-" + companyId;
    }
}

3. Facade 外观类

public class Facade {
    private final AdminOfIndustry admin = new AdminOfIndustry();
    private final Bank bank = new Bank();
    private final Taxation taxation = new Taxation();

    // 统一封装的流程:注册公司
    public Company openCompany(String name) {
        Company c = this.admin.register(name);
        String bankAccount = this.bank.openAccount(c.getId());
        c.setBankAccount(bankAccount);
        String taxCode = this.taxation.applyTaxCode(c.getId());
        c.setTaxCode(taxCode);
        return c;
    }
}

4. 客户端调用

public class Main {
    public static void main(String[] args) {
        Facade facade = new Facade();
        Company company = facade.openCompany("Facade Software Ltd.");
        System.out.println("最终公司信息: " + company);
    }
}

🔹 运行结果

工商局:注册公司 -> Facade Software Ltd.
银行:为公司ID ID-1694000000000 开设账户
税务局:为公司ID ID-1694000000000 分配纳税号
最终公司信息: Company{id='ID-1694000000000', name='Facade Software Ltd.', bankAccount='BANK-ID-1694000000000', taxCode='TAX-ID-1694000000000'}

🔹 通俗解释

  • 没有 Facade:客户端要自己调用工商局 → 银行 → 税务局,步骤繁琐,容易出错。
  • 有了 Facade:客户端只调用 facade.openCompany(),内部的具体细节全部隐藏,外部世界只看到一个统一接口。

🔹 应用场景

  • Web系统RestApiController 就是一个 Facade,把内部多个服务统一暴露给外部。
  • 微服务网关(Gateway):对外提供统一入口,内部再转发给不同微服务,典型的 系统级 Facade
  • 第三方SDK:比如支付宝/微信支付的 SDK,就是外观模式的例子,屏蔽了底层复杂接口。

✅ 一句话总结:Facade 模式就是给复杂系统加一个“中介”,让外部调用只面对统一接口,而不用管内部多复杂。


Facade模式 vs Adapter模式 对比

模式 核心目的 例子
Facade(外观模式) 为复杂系统提供一个统一接口,让客户端更容易使用 (简化操作) 注册公司流程:工商局、银行、税务局 → 客户端只调用 facade.openCompany()
Adapter(适配器模式) 将一个接口转换成客户端期望的另一个接口 (接口兼容) 有一个老接口 OldPayment,新系统需要 NewPayment → 写 PaymentAdapter 把旧接口改成新接口可用

🔹 关注点

  • Facade:关注的是 简化操作流程

    • 多个子系统 → 统一入口
    • 不改变子系统接口,只是把调用顺序/组合封装起来
  • Adapter:关注的是 接口兼容

    • 旧接口或第三方接口 → 转换成客户端可用的接口
    • 改变接口表现,但通常只针对一个对象或类

🔹 UML 简单示意

Facade

客户端
   |
   v
+--------+
| Facade |
+--------+
   |
   v
+--------+   +------+   +--------+
| 子系统1 |  | 子系统2 |  | 子系统3 |
+--------+   +------+   +--------+

Adapter

客户端
   |
   v
+--------+
| Adapter |
+--------+
   |
   v
+-------------+
| 被适配的接口 |
+-------------+

🔹 小结一句话

  • Facade → “简化操作”,让复杂系统更好用
  • Adapter → “接口转换”,让不兼容的接口可用
posted @ 2025-09-06 12:36  AlphaGeek  阅读(58)  评论(0)    收藏  举报