Facade Pattern,由統一的入口介面來做事

什麼是 Facade Pattern?

實作不依賴多個類別,而是依賴介面,並把這些類別實作在此介面

問題情境

(相關的 code 在Github - go-design-patterns)

當 PS5 啟動時,會用到許多 CPU 相關的指令集,以下方範例來說即是StrcutA{}StrcutB{},如果未來要更改StrcutA{}StrcutB{}DoAction()function 呼叫方式,或者StrcutA{}被棄用要改用StructC{},都必須要修改PS5{}.Start()的實作。

package main

import "fmt"

type StructA struct{}

func (s StructA) DoAction() {}

type StructB struct{}

func (s StructB) DoAction() {}

type PS5 struct {
}

func (p PS5) Start() {
	strcutA := StructA{}
	strcutB := StructB{}
	strcutA.DoAction()
	strcutB.DoAction()
	fmt.Println("start ps5...done!")
}

func main() {
	ps5 := PS5{}
	ps5.Start()
}

我們需要一個方式,能讓做這些更改時PS5{}.Start()不需要修改。

解決方式

PS5{}.Start()可以只依賴特定介面CPUFacade interface 的Work(),所以可以將StrcutA{}StructB{}的使用方式都封裝在Work()中,就算後續StrcutA{}StructB{}有變更呼叫方式或是棄用,都不影響PS5{}.Start()的呼叫。

package main

import "fmt"

type CPUFacade interface {
	Work()
}

type StructA struct{}

func (s StructA) DoAction() {}

type StructB struct{}

func (s StructB) DoAction() {}

type CPU struct{}

func (c CPU) Work() {
	strcutA := StructA{}
	strcutB := StructB{}
	strcutA.DoAction()
	strcutB.DoAction()
}

type PS5 struct {
	cpu CPUFacade
}

func (p PS5) Start() {
	p.cpu.Work()
	fmt.Println("start ps5...done!")
}

func main() {
	ps5 := PS5{cpu: CPU{}}
	ps5.Start()
}
comments powered by Disqus