自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊聊前端領(lǐng)域那些“門面”

開(kāi)發(fā) 前端
門面模式(Facade)是 23 種經(jīng)典設(shè)計(jì)模式之一,也叫外觀模式,是通過(guò)在客戶端和子系統(tǒng)之間引入一個(gè)中間層,將內(nèi)部復(fù)雜度隱藏,暴露出一個(gè)簡(jiǎn)單易用的接口。

[[410537]]

本文轉(zhuǎn)載自微信公眾號(hào)「神光的編程秘籍」,作者神說(shuō)要有光zxg。轉(zhuǎn)載本文請(qǐng)聯(lián)系神光的編程秘籍公眾號(hào)。

門面模式(Facade)是 23 種經(jīng)典設(shè)計(jì)模式之一,也叫外觀模式,是通過(guò)在客戶端和子系統(tǒng)之間引入一個(gè)中間層,將內(nèi)部復(fù)雜度隱藏,暴露出一個(gè)簡(jiǎn)單易用的接口。

引入門面模式之后,對(duì)客戶端來(lái)說(shuō),使用起來(lái)會(huì)簡(jiǎn)單很多,不再需要了解具體的細(xì)節(jié)。

比如,沒(méi)用門面模式之前,可能是這樣的調(diào)用關(guān)系,客戶端需要了解每一個(gè)內(nèi)部細(xì)節(jié)

而用了門面模式之后,客戶端不再需要了解具體每一個(gè)模塊,只需要把自己的需求告訴 Facade,然后它去調(diào)用內(nèi)部模塊

加了一個(gè)門面,有改變功能么?并沒(méi)有,只是使得對(duì)外的接口更易用了。而這,就是門面模式的意義:封裝內(nèi)部細(xì)節(jié),簡(jiǎn)化調(diào)用

其實(shí)在軟件領(lǐng)域這種門面太多了,各種 DSL(領(lǐng)域特定語(yǔ)言) 包括 html、css 還有 vue 的 template、react 的 jsx 都算是門面,babel 和 eslint 的 preset 也是門面。

下面我們分別來(lái)分析一下。

簡(jiǎn)化 dom 創(chuàng)建的門面:html

瀏覽器提供了 dom api,基于 dom api 我們就可以構(gòu)建 dom 樹(shù),那為什么需要 html 呢?不用 html 可以么?

比如 dom api 創(chuàng)建 dom:

  1. const div = document.createElement('div'); 
  2. div.className = "a"
  3.  
  4. const img = document.createElement('img'); 
  5. img.src="./b.jpg" 
  6.  
  7. div.appendChild(img); 

和 html 描述 dom:

  1. <div class="a"
  2.     <img src="./b.jpg"
  3. </div> 

 

 

兩者并沒(méi)有區(qū)別。

所以,html 并沒(méi)有增加功能,它只是簡(jiǎn)化了 dom 操作,這種明顯就是一種門面模式,不過(guò)是通過(guò) DSL 的方式。

DSL 是指領(lǐng)域特定語(yǔ)言,設(shè)計(jì)一種語(yǔ)法來(lái)簡(jiǎn)化邏輯的描述,然后通過(guò)解析該語(yǔ)言來(lái)專程描述的目標(biāo)。瀏覽器就是通過(guò)解析 html 來(lái)構(gòu)建 dom 樹(shù)的。

簡(jiǎn)化樣式描述的門面:css

css 同樣也是一種 dsl,為了簡(jiǎn)化樣式信息的描述。

比如直接給 dom 添加樣式會(huì)比較麻煩:

  1. const div = document.querySelector('.a'); 
  2. div.style.backgroundColor = 'blue'
  3.  
  4. const img = div.querySelector('img'); 
  5. img.style.border = '2px'

而通過(guò) css 來(lái)添加就簡(jiǎn)單很多:

  1. .a { 
  2.     background-color: blue; 
  3. .a img { 
  4.     border: 2px; 

css 有增加新功能么?沒(méi)有,它只是使得樣式描述更簡(jiǎn)單,同樣,css 這種 dsl 也是由瀏覽器來(lái)解析的。

vue 的 template

我們知道操作視圖基于 dom api 就足夠了,前端框架就是把數(shù)據(jù)映射到視圖,而映射的目標(biāo)也是 dom api(當(dāng)然,中間有了一層虛擬 dom,那么 api 也是先創(chuàng)建虛擬 dom),但是 dsl 就沒(méi)必要選擇用 html 了,完全可以用其他的更適合自己特點(diǎn)的方式來(lái)描述。

vue 選擇了 template:

如果直接用 api 描述視圖,不夠直觀:

  1. render: function (createElement) { 
  2.   return createElement('h1', this.blogTitle) 

vue 選擇了 template 的方式,類似 html:

  1. <h1>{{ blogTitle }}</h1> 

 

這樣并沒(méi)有增加功能,只是讓開(kāi)發(fā)者使用框架描述視圖的時(shí)候更簡(jiǎn)單,而且 vue 還支持過(guò)濾器、指令、插值語(yǔ)法等功能。

但是引入了 template 的 dsl,也就需要編譯了,不像 html 是瀏覽器解析的,這個(gè)自定義 dsl 需要用自己的編譯器來(lái)解析,所以 vue 內(nèi)部有一個(gè) template compiler 來(lái)把模版轉(zhuǎn)為 render 函數(shù)。

react 的 jsx

react 同樣也是要把對(duì)視圖的描述映射成真正的 dom(中間有層虛擬 dom),首先會(huì)提供 api 的方式,但是為了簡(jiǎn)化使用,會(huì)提供了描述視圖的方式:jsx。

直接用 api 的方式比較麻煩:

  1. const title = React.createElement("h1", {className: "main"}, "Hello React"); 

jsx 的方式就簡(jiǎn)單很多:

  1. const title = ( 
  2.   <h1>Hello React</h1> 
  3. ); 

vue 和 react 選擇了不同的 dsl。我們知道 dsl 是需要編譯成具體的 api 調(diào)用的,vue 是在框架內(nèi)部實(shí)現(xiàn)的,而 react 的 jsx 則是 babel 實(shí)現(xiàn)(因?yàn)槭?js 語(yǔ)法的擴(kuò)充)。

可以看到不管是 vue 的 template,還是 react 的 jsx 都沒(méi)有增加新的功能,增加這樣一層 dsl 只是為了簡(jiǎn)化開(kāi)發(fā)者對(duì)視圖的描述,和 html 的設(shè)計(jì)目的一致,都是門面模式的思想。

babel 的 preset

babel 是做代碼轉(zhuǎn)換的,把 es next 的語(yǔ)法,轉(zhuǎn)成目標(biāo)環(huán)境支持的 js 語(yǔ)法,具體完成轉(zhuǎn)換的是一個(gè)個(gè)插件。但是如果開(kāi)發(fā)者直接去指定插件太過(guò)麻煩,比如 es2015 就有一系列插件,而 es2016 又有一堆,如果由開(kāi)發(fā)者去指定,那使用起來(lái)太過(guò)復(fù)雜。所以 babel 設(shè)計(jì)出了 preset。

babel6 的 preset 有 preset-es2015、 preset-es2016 等,他們內(nèi)部就是一系列插件。而 babel7 進(jìn)一步簡(jiǎn)化成了 preset-env,只要通過(guò) targets 指定目標(biāo)環(huán)境,那么就會(huì)自動(dòng)選出一系列插件來(lái)使用。

preset 有實(shí)現(xiàn)什么新功能么?沒(méi)有,最終轉(zhuǎn)換還是由插件來(lái)做的。但是 preset 簡(jiǎn)化了開(kāi)發(fā)者使用 babel 的成本,所以這也是一種典型的門面模式。

總結(jié)

門面模式是軟件領(lǐng)域特別常見(jiàn)的一種模式,就是當(dāng)暴露給客戶端的子系統(tǒng)特別復(fù)雜的時(shí)候,通過(guò)增加一層門面,由他去和具體的子系統(tǒng)打交道,隔離復(fù)雜度,讓軟件的使用變得簡(jiǎn)單。通過(guò)隔離復(fù)雜度,讓復(fù)雜度得到很好的治理,不然的話可能會(huì)隨著迭代而使用起來(lái)越來(lái)越復(fù)雜。

前端領(lǐng)域常見(jiàn)的 html、css、還有 vue 的 tempalte 以及 react 的 jsx 都是 dsl,dsl 的目的就是為了簡(jiǎn)化調(diào)用,是門面模式的典型實(shí)現(xiàn)。(template 和 jsx 要由自己做編譯,而 html、css 是瀏覽器做的編譯)。

此外,babel 和 eslint 等的 preset 也是為了簡(jiǎn)化使用成本而引入的,不然用戶就要直接面對(duì)各種復(fù)雜的插件配置。

 

門面模式并沒(méi)有引入新的功能實(shí)現(xiàn),只是為了簡(jiǎn)化系統(tǒng)使用成本而引入的一個(gè)入口。如果遇到系統(tǒng)使用特別復(fù)雜的時(shí)候,不妨通過(guò)引入一個(gè)門面(封裝成 api 或者 dsl 的形式)來(lái)簡(jiǎn)化吧。

 

責(zé)任編輯:武曉燕 來(lái)源: 神光的編程秘籍
相關(guān)推薦

2022-05-23 08:34:08

微前端微服務(wù)開(kāi)發(fā)

2021-06-02 08:33:31

TPCTPC-H系統(tǒng)

2022-02-15 22:45:00

前端設(shè)計(jì)模式

2022-11-14 08:44:56

前端門面模式接口

2018-05-09 08:18:26

微服務(wù)改造架構(gòu)

2022-09-09 08:08:28

開(kāi)源項(xiàng)目服務(wù)

2021-05-10 08:58:09

Harbor架構(gòu)Registry 服務(wù)

2013-01-11 16:05:41

求職招聘

2022-04-14 11:50:39

函數(shù)組件hook

2023-07-31 08:21:22

語(yǔ)法校對(duì)器Pick

2017-03-16 12:08:09

OpenstackCompute DriLibvirt

2022-06-02 08:42:15

Redis數(shù)據(jù)庫(kù)

2020-11-30 13:10:39

MySQL安全服務(wù)器

2021-01-13 11:11:29

TCP連接耗時(shí)網(wǎng)絡(luò)協(xié)議

2021-08-06 11:50:49

Linux 字節(jié)對(duì)齊Linux 系統(tǒng)

2012-08-30 09:41:23

移動(dòng)應(yīng)用開(kāi)發(fā)

2018-04-24 09:05:09

容器存儲(chǔ)接口

2020-09-17 13:43:03

等保2.0網(wǎng)絡(luò)安全漏洞

2024-03-27 07:58:23

開(kāi)源軟件MongoDB

2019-01-07 12:02:02

TCP長(zhǎng)連接Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)