设计模式-12-门面模式

**门面模式(外观模式)**是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。

问题描述:假设必须在代码中使用某个复杂的库或框架中的众多对象。 正常情况下,需要负责所有对象的初始化工作、 管理其依赖关系并按正确的顺序执行方法等。最终, 程序中类的业务逻辑将与第三方类的实现细节紧密耦合, 使得理解和维护代码的工作很难进行。

逻辑结构

Facade

代码实现

代码路径:https://github.com/XBoom/DesignPatterns/tree/main/11_Facade

  1. 比如有三个组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // ComponentA 子系统中的组件
    type ComponentA struct{}

    func (c *ComponentA) MethodA() {
    fmt.Println("ComponentA: MethodA")
    }

    type ComponentB struct{}

    func (c *ComponentB) MethodB() {
    fmt.Println("ComponentB: MethodB")
    }

    type ComponentC struct{}

    func (c *ComponentC) MethodC() {
    fmt.Println("ComponentC: MethodC")
    }
  2. 使用门面模式统一处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // Facade 门面
    type Facade struct {
    componentA *ComponentA
    componentB *ComponentB
    componentC *ComponentC
    }

    func NewFacade() *Facade {
    return &Facade{
    componentA: &ComponentA{},
    componentB: &ComponentB{},
    componentC: &ComponentC{},
    }
    }

    // Operation 提供简单统一的接口给客户端使用
    func (f *Facade) Operation() {
    fmt.Println("Facade: Operation")
    f.componentA.MethodA()
    f.componentB.MethodB()
    f.componentC.MethodC()
    }

运行

1
2
facade := NewFacade()
facade.Operation()

结果

1
2
3
4
Facade: Operation
ComponentA: MethodA
ComponentB: MethodB
ComponentC: MethodC

适用场景

  1. 如果需要一个指向复杂子系统的直接接口,且该接口的功能有限,则可以使用门面模式
  2. 如果需要将子系统组织为多层结构,可以使用外观
  3. 门面模式适用于一个系统的外部和内部之间有着很复杂的交互关系,并且希望通过一个简单的接口对其进行封装的场景,如果门面设计不当,可能会导致门面过于庞大和复杂

参考链接

  1. https://refactoringguru.cn/design-patterns/facade
  2. https://lailin.xyz/post/facade.html