Facade Design Pattern

门面(外观)模式(Facade Design Pattern)是一种结构型设计模式。意图隐藏底层系统的复杂性,并为客户端提供一个简单易用的操作界面

它为系统中许多底层接口提供了统一的接口,因此从客户端的角度来看,减少了需要操作的系统元素数量,它更易于使用。 业务架构设计层次划分时,BFF(Backend For Frontend)层便是对该模式很好的应用。

UML Diagram

image

Example

Question:

整合一下服务接口,以服务 A 的 DoSomething 接口对外提供服务:
- Sub1 服务的 DoX()
- Sub2 服务的 DoY()
- Sub3 服务的 DoZ()

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

import "fmt"

type AFacade struct {
	bSvc *SubSvc1
	cSvc *SubSvc2
	dSvc *SubSvc3
}

func NewAFacde() *AFacade {
	return &AFacade{
		bSvc: &SubSvc1{},
		cSvc: &SubSvc2{},
		dSvc: &SubSvc3{},
	}
}

func (a *AFacade) DoSomething() {
	fmt.Println("Start all tasks......")
	a.bSvc.DoX()
	a.cSvc.DoY()
	a.dSvc.DoZ()
	fmt.Println("Completed all tasks")
}

type SubSvc1 struct{}

func (svc *SubSvc1) DoX() {
	fmt.Println("Completed task X by SubSvc1")
}

type SubSvc2 struct{}

func (svc *SubSvc2) DoY() {
	fmt.Println("Completed task Y by SubSvc2")
}

type SubSvc3 struct{}

func (svc *SubSvc3) DoZ() {
	fmt.Println("Completed task Z by SubSvc3")
}

func main() {
	a := NewAFacde()
	a.DoSomething()
}

Output:

Start all tasks......
Completed task X by SubSvc1
Completed task Y by SubSvc2
Completed task Z by SubSvc3
Completed all tasks

Application Scenarios

  1. 解决易用性问题:对多个复杂的底层系统接口的组合;对细粒度接口的组合。
  2. 解决性能问题:通过增加一个中间层来减少对后端接口调用次数,减少网络延时。
  3. 架构边界设计:不完全架构边界(最终完整架构边界的临时替代品)实现策略的一种。
  4. 有没有发现这个代码结构与依赖注入的写法一致?

Referances

https://time.geekbang.org/column/article/206409

https://golangbyexample.com/facade-design-pattern-in-golang/

https://pkg.go.dev/github.com/google/wire