摘要:外觀模式的目的在于降低系統(tǒng)的復(fù)雜程度。在不引入抽象外觀類(lèi)的情況下,增加新的子系統(tǒng)可能需要修改外觀類(lèi)或客戶端的源代碼,違背了開(kāi)閉原則。
外觀模式
外觀模式(Facade Pattern):外部與一個(gè)子系統(tǒng)的通信必須通過(guò)一個(gè)統(tǒng)一的外觀對(duì)象進(jìn)行,為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,外觀模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。外觀模式又稱(chēng)為門(mén)面模式,它是一種對(duì)象結(jié)構(gòu)型模式。
Laravel中我們常用到的Route、Redis、Auth這些Facade就是外觀模式的具體實(shí)現(xiàn), 在Laravel中設(shè)計(jì)了多個(gè)外觀類(lèi),每個(gè)外觀類(lèi)繼承自統(tǒng)一的抽象外觀類(lèi),在抽象外觀類(lèi)里提供了通過(guò)外觀類(lèi)訪問(wèn)其背后子系統(tǒng)的基礎(chǔ)方法。
對(duì)于新的業(yè)務(wù)需求,不要修改原有外觀類(lèi),而應(yīng)該增加一個(gè)新的具體外觀類(lèi),由新的具體外觀類(lèi)來(lái)關(guān)聯(lián)新的子系統(tǒng)對(duì)象,同時(shí)通過(guò)修改配置文件來(lái)達(dá)到不修改源代碼并更換外觀類(lèi)的目的。
下面是一個(gè)簡(jiǎn)單的外觀模式的例子,并沒(méi)有引入抽象外觀類(lèi),在介紹Laravel Facades的文章中我們會(huì)看到Laravel里提供了一個(gè)抽象外觀類(lèi)從而讓我們能夠方便的根據(jù)需要增加新子系統(tǒng)的外觀類(lèi),并讓外觀類(lèi)能夠正確代理到其對(duì)應(yīng)的子系統(tǒng)(或者叫服務(wù))。
模式結(jié)構(gòu)外觀模式包含如下角色:
Facade 外觀角色
SubSystem 子系統(tǒng)角色
代碼示例operation(); } } class Facade { private $systemA; private $systemB; public function __construct() { $this->systemA = new SystemA; $this->systemB = new SystemB; } public function operation() { $this->systemA->operationA(); $this->systemB->operationB(); } } class SystemA { public function operationA() { // } } class SystemB { public function operationB() { // } }模式分析
根據(jù)“單一職責(zé)原則”,在軟件中將一個(gè)系統(tǒng)劃分為若干個(gè)子系統(tǒng)有利于降低整個(gè)系統(tǒng)的復(fù)雜性,一個(gè)常見(jiàn)的設(shè)計(jì)目標(biāo)是使子系統(tǒng)間的通信和相互依賴(lài)關(guān)系達(dá)到最小,而達(dá)到該目標(biāo)的途徑之一就是引入一個(gè)外觀對(duì)象,它為子系統(tǒng)的訪問(wèn)提供了一個(gè)簡(jiǎn)單而單一的入口。 -外觀模式也是“迪米特法則”的體現(xiàn),通過(guò)引入一個(gè)新的外觀類(lèi)可以降低原有系統(tǒng)的復(fù)雜度,同時(shí)降低客戶類(lèi)與子系統(tǒng)類(lèi)的耦合度。 - 外觀模式要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信通過(guò)一個(gè)統(tǒng)一的外觀對(duì)象進(jìn)行,外觀類(lèi)將客戶端與子系統(tǒng)的內(nèi)部復(fù)雜性分隔開(kāi),使得客戶端只需要與外觀對(duì)象打交道,而不需要與子系統(tǒng)內(nèi)部的很多對(duì)象打交道。 -外觀模式的目的在于降低系統(tǒng)的復(fù)雜程度。 -外觀模式從很大程度上提高了客戶端使用的便捷性,使得客戶端無(wú)須關(guān)心子系統(tǒng)的工作細(xì)節(jié),通過(guò)外觀角色即可調(diào)用相關(guān)功能。
缺點(diǎn)外觀模式的缺點(diǎn)
不能很好地限制客戶使用子系統(tǒng)類(lèi),如果對(duì)客戶訪問(wèn)子系統(tǒng)類(lèi)做太多的限制則減少了可變性和靈活性。
在不引入抽象外觀類(lèi)的情況下,增加新的子系統(tǒng)可能需要修改外觀類(lèi)或客戶端的源代碼,違背了“開(kāi)閉原則”。
模式擴(kuò)展一個(gè)系統(tǒng)有多個(gè)外觀類(lèi)
在外觀模式中,通常只需要一個(gè)外觀類(lèi),并且此外觀類(lèi)只有一個(gè)實(shí)例,換言之它是一個(gè)單例類(lèi)。在很多情況下為了節(jié)約系統(tǒng)資源,一般將外觀類(lèi)設(shè)計(jì)為單例類(lèi)。當(dāng)然這并不意味著在整個(gè)系統(tǒng)里只能有一個(gè)外觀類(lèi),在一個(gè)系統(tǒng)中可以設(shè)計(jì)多個(gè)外觀類(lèi),每個(gè)外觀類(lèi)都負(fù)責(zé)和一些特定的子系統(tǒng)交互,向用戶提供相應(yīng)的業(yè)務(wù)功能。
不要試圖通過(guò)外觀類(lèi)為子系統(tǒng)增加新行為
不要通過(guò)繼承一個(gè)外觀類(lèi)在子系統(tǒng)中加入新的行為,這種做法是錯(cuò)誤的。外觀模式的用意是為子系統(tǒng)提供一個(gè)集中化和簡(jiǎn)化的溝通渠道,而不是向子系統(tǒng)加入新的行為,新的行為的增加應(yīng)該通過(guò)修改原有子系統(tǒng)類(lèi)或增加新的子系統(tǒng)類(lèi)來(lái)實(shí)現(xiàn),不能通過(guò)外觀類(lèi)來(lái)實(shí)現(xiàn)。
抽象外觀類(lèi)的引入
外觀模式最大的缺點(diǎn)在于違背了“開(kāi)閉原則”,當(dāng)增加新的子系統(tǒng)或者移除子系統(tǒng)時(shí)需要修改外觀類(lèi),可以通過(guò)引入抽象外觀類(lèi)在一定程度上解決該問(wèn)題,客戶端針對(duì)抽象外觀類(lèi)進(jìn)行編程。對(duì)于新的業(yè)務(wù)需求,不修改原有外觀類(lèi),而對(duì)應(yīng)增加一個(gè)新的具體外觀類(lèi),由新的具體外觀類(lèi)來(lái)關(guān)聯(lián)新的子系統(tǒng)對(duì)象,同時(shí)通過(guò)修改配置文件來(lái)達(dá)到不修改源代碼并更換外觀類(lèi)的目的。
總結(jié)在外觀模式中,外部與一個(gè)子系統(tǒng)的通信必須通過(guò)一個(gè)統(tǒng)一的外觀對(duì)象進(jìn)行,為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,外觀模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。外觀模式又稱(chēng)為門(mén)面模式,它是一種對(duì)象結(jié)構(gòu)型模式。
外觀模式包含兩個(gè)角色:外觀角色是在客戶端直接調(diào)用的角色,在外觀角色中可以知道相關(guān)的(一個(gè)或者多個(gè))子系統(tǒng)的功能和責(zé)任,它將所有從客戶端發(fā)來(lái)的請(qǐng)求委派到相應(yīng)的子系統(tǒng)去,傳遞給相應(yīng)的子系統(tǒng)對(duì)象處理;在軟件系統(tǒng)中可以同時(shí)有一個(gè)或者多個(gè)子系統(tǒng)角色,每一個(gè)子系統(tǒng)可以不是一個(gè)多帶帶的類(lèi),而是一個(gè)類(lèi)的集合,它實(shí)現(xiàn)子系統(tǒng)的功能。
外觀模式要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信通過(guò)一個(gè)統(tǒng)一的外觀對(duì)象進(jìn)行,外觀類(lèi)將客戶端與子系統(tǒng)的內(nèi)部復(fù)雜性分隔開(kāi),使得客戶端只需要與外觀對(duì)象打交道,而不需要與子系統(tǒng)內(nèi)部的很多對(duì)象打交道。
外觀模式主要優(yōu)點(diǎn)在于對(duì)客戶屏蔽子系統(tǒng)組件,減少了客戶處理的對(duì)象數(shù)目并使得子系統(tǒng)使用起來(lái)更加容易,它實(shí)現(xiàn)了子系統(tǒng)與客戶之間的松耦合關(guān)系,并降低了大型軟件系統(tǒng)中的編譯依賴(lài)性,簡(jiǎn)化了系統(tǒng)在不同平臺(tái)之間的移植過(guò)程;其缺點(diǎn)在于不能很好地限制客戶使用子系統(tǒng)類(lèi),而且在不引入抽象外觀類(lèi)的情況下,增加新的子系統(tǒng)可能需要修改外觀類(lèi)或客戶端的源代碼,違背了“開(kāi)閉原則”。
外觀模式適用情況包括:要為一個(gè)復(fù)雜子系統(tǒng)提供一個(gè)簡(jiǎn)單接口;客戶程序與多個(gè)子系統(tǒng)之間存在很大的依賴(lài)性;在層次化結(jié)構(gòu)中,需要定義系統(tǒng)中每一層的入口,使得層與層之間不直接產(chǎn)生聯(lián)系。
本文已經(jīng)收錄在系列文章Laravel源碼學(xué)習(xí)里,歡迎訪問(wèn)閱讀。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/29143.html
摘要:外觀模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。將使用者與子系統(tǒng)從直接耦合,轉(zhuǎn)變成由外觀類(lèi)提供統(tǒng)一的接口給使用者使用,以降低客戶端與子系統(tǒng)之間的耦合度。接下來(lái)將深入分析外觀服務(wù)的加載過(guò)程。引導(dǎo)程序?qū)⒃谔幚碚?qǐng)求是完成引導(dǎo)啟動(dòng)。 本文首發(fā)于 深入淺出 Laravel 的 Facade 外觀系統(tǒng),轉(zhuǎn)載請(qǐng)注明出處。 今天我們將學(xué)習(xí) Laravel 核心架構(gòu)中的另一個(gè)主題「Fac...
摘要:本文來(lái)自原文鏈接歡迎作客我們的學(xué)習(xí)群該篇屬于底層核心技術(shù)實(shí)戰(zhàn)揭秘這一課程底層核心概念解析這一章的擴(kuò)展閱讀??紤]到學(xué)員們的基礎(chǔ)差異,為了避免視頻當(dāng)中過(guò)于詳細(xì)而連篇累牘,故將一些底層實(shí)現(xiàn)相關(guān)的知識(shí)點(diǎn)以文章形式呈現(xiàn),供大家預(yù)習(xí)和隨時(shí)查閱。 本文來(lái)自pilishen.com----原文鏈接; 歡迎作客我們的php&Laravel學(xué)習(xí)群:109256050該篇屬于《Laravel底層核心技術(shù)實(shí)戰(zhàn)...
摘要:模式定義觀察者模式定義對(duì)象間的一種一對(duì)多依賴(lài)關(guān)系,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí),其相關(guān)依賴(lài)對(duì)象皆得到通知并被自動(dòng)更新。 觀察者模式 Laravel的Event事件系統(tǒng)提供了一個(gè)簡(jiǎn)單的觀察者模式實(shí)現(xiàn),能夠訂閱和監(jiān)聽(tīng)?wèi)?yīng)用中發(fā)生的各種事件,在PHP的標(biāo)準(zhǔn)庫(kù)(SPL)里甚至提供了三個(gè)接口SplSubject, SplObserver, SplObjectStorage來(lái)讓開(kāi)發(fā)者更容易地實(shí)現(xiàn)觀...
摘要:可以為服務(wù)提供者的方法設(shè)置類(lèi)型提示。方法將在所有其他服務(wù)提供者均已注冊(cè)之后調(diào)用。所有服務(wù)提供者都在配置文件中注冊(cè)。可以選擇推遲服務(wù)提供者的注冊(cè),直到真正需要注冊(cè)綁定時(shí),這樣可以提供應(yīng)用程序的性能。 本文最早發(fā)布于 Rootrl的Blog 導(dǎo)言 Laravel是一款先進(jìn)的現(xiàn)代化框架,里面有一些概念非常重要。在上手Laravel之前,我認(rèn)為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP...
摘要:前言年底了不太忙,最近一段時(shí)間也一直在研究,就想寫(xiě)篇關(guān)于比較深一點(diǎn)的教程系列啥的,于是就找到站長(zhǎng)給開(kāi)了寫(xiě)教程的渠道。優(yōu)點(diǎn)的就是為藝術(shù)家創(chuàng)造的框架,它也是工程化的趨勢(shì)。項(xiàng)目維護(hù)方便也是事實(shí)。如果有遇到問(wèn)題可以直接在教程下面留言。 前言 年底了不太忙,最近一段時(shí)間也一直在研究laravel,就想寫(xiě)篇關(guān)于laravel比較深一點(diǎn)的教程系列啥的,于是就找到站長(zhǎng)給開(kāi)了寫(xiě)教程的渠道。由于第一次寫(xiě),...
閱讀 1696·2021-11-23 09:51
閱讀 3218·2021-09-26 10:21
閱讀 814·2021-09-09 09:32
閱讀 893·2019-08-29 16:06
閱讀 3322·2019-08-26 13:36
閱讀 783·2019-08-26 10:56
閱讀 2575·2019-08-26 10:44
閱讀 1155·2019-08-23 14:04