掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流
大家好,這里是每周都在陪你一起進步的網(wǎng)管~!今天繼續(xù)設計模式學習之旅,這次咱們分享個大家每個人在寫代碼時都用過,但面試時經(jīng)常忽視它的設計模式--外觀模式,我們一起來看看吧。

創(chuàng)新互聯(lián)專注于玉環(huán)網(wǎng)站建設服務及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供玉環(huán)營銷型網(wǎng)站建設,玉環(huán)網(wǎng)站制作、玉環(huán)網(wǎng)頁設計、玉環(huán)網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務,打造玉環(huán)網(wǎng)絡公司原創(chuàng)品牌,更為您提供玉環(huán)網(wǎng)站排名全網(wǎng)營銷落地服務。
現(xiàn)代的軟件系統(tǒng)都非常復雜,盡管我們已經(jīng)想盡一切方法將其“分而治之”,把一個系統(tǒng)劃分為好幾個較小的子系統(tǒng)了,但是仍然可能會存在這樣的問題:子系統(tǒng)內(nèi)有非常多的類,客戶端往往需要和許多對象打交道之后才能完成想要完成的功能。
在我們的生活中醫(yī)院就是這樣的。一般的醫(yī)院都會分為掛號、門診、化驗、收費、取藥等??床〉牟∪艘胫魏米约旱牟。ㄏ喈斢谝粋€客戶端想要實現(xiàn)自己的功能)就要和醫(yī)院的各個部門打交道。首先,病人需要掛號,然后門診,如果醫(yī)生要求化驗的話,病人就要去化驗,然后再回到門診室,最后拿藥,經(jīng)過一系列復雜的過程后才能完成看病的過程。如下圖所示:
如果我們在醫(yī)院設立一個接待員的話,病人只負責和接待員接觸,由接待員負責與醫(yī)院的各個部門打交道,如下圖所示:
醫(yī)院設立的接待員的角色就是我們今天要介紹的外觀模式,系統(tǒng)通過引入外觀模式讓需要調(diào)用多個子系統(tǒng)各自部分的功能接口以完成的需求,變?yōu)檎{(diào)用方只需要跟外觀提供的統(tǒng)一功能進行交互即可。
引入外觀模式帶來的變化
外觀模式又稱為門面模式,它是一種結構型模式。引入外觀模式后調(diào)用方與多個子系統(tǒng)的通信必須通過一個統(tǒng)一的外觀對象進行,外觀模式為子系統(tǒng)中的功能接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這些子系統(tǒng)更加容易使用。
外觀模式的結構其實很簡單,用一個UML圖就能描述清楚外觀模式里擁有哪些角色以及它們各自的特點,下面我們看一下外觀模式的類結構。
下面我們用Go代碼實現(xiàn)一個外觀模式。
這個例子里我們把電腦擁有的CPU、RAM內(nèi)存和硬盤視為子系統(tǒng),調(diào)用方想啟動電腦就得分別啟動這三個子系統(tǒng)才行,所以我們在子系統(tǒng)上增加一個外觀對象,讓調(diào)用方直接調(diào)用外觀對象,由外觀對象再去分別對接子系統(tǒng)最終完成電腦的啟動。
該實例源代碼引用自:https://github.com/yksz/go-design-patterns/blob/master/structure/facade.go
package main
import (
"fmt"
)
const (
BOOT_ADDRESS = 0
BOOT_SECTOR = 0
SECTOR_SIZE = 0
)
type CPU struct{}
func (c *CPU) Freeze() {
fmt.Println("CPU.Freeze()")
}
func (c *CPU) Jump(position int) {
fmt.Println("CPU.Jump()")
}
func (c *CPU) Execute() {
fmt.Println("CPU.Execute()")
}
type Memory struct{}
func (m *Memory) Load(position int, data []byte) {
fmt.Println("Memory.Load()")
}
type HardDrive struct{}
func (hd *HardDrive) Read(lba int, size int) []byte {
fmt.Println("HardDrive.Read()")
return make([]byte, 0)
}
type ComputerFacade struct {
processor *CPU
ram *Memory
hd *HardDrive
}
func NewComputerFacade() *ComputerFacade {
return &ComputerFacade{new(CPU), new(Memory), new(HardDrive)}
}
func (c *ComputerFacade) start() {
c.processor.Freeze()
c.ram.Load(BOOT_ADDRESS, c.hd.Read(BOOT_SECTOR, SECTOR_SIZE))
c.processor.Jump(BOOT_ADDRESS)
c.processor.Execute()
}
func main() {
computer := NewComputerFacade()
computer.start()
}
本文的完整源碼,已經(jīng)同步收錄到我整理的電子教程里啦,可向我的公眾號「網(wǎng)管叨bi叨」發(fā)送關鍵字【設計模式】領取。
公眾號「網(wǎng)管叨bi叨」發(fā)送關鍵字【設計模式】領取。
要說外觀模式在實際開發(fā)中的應用,首先讓我想起來的就是Java 里的Slf4j,它是一個抽象層,讓用戶對日志的操作統(tǒng)一由Slf4j跟用戶去對接,用戶用這個抽象層的API來寫日志, 底層具體用什么日志工具實現(xiàn)用戶完全不用關心,由Slf4j來對接Log4j、LogBack 這些日志工具,這樣就可以更方便地移植了。
這個抽象層 Slf4j 就是Simple logging Facade For Java 的簡稱,從名字里我們也能看出來,它是一個外觀模式的實踐應用,由于普及度很高,很多講解外觀模式的教程里都會提及它,拿它的實現(xiàn)來給讀者做分析。
外觀模式的優(yōu)點
外觀模式的缺點

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流