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

前端代碼的三種設(shè)計模式

開發(fā) 前端
前端作為軟件工程長期發(fā)展出來的一個獨立分支,一直沒有屬于自己的特定的代碼設(shè)計模式,最近我們在實踐中對一些發(fā)源于面向?qū)ο蟮拇a設(shè)計做了一些總結(jié),總結(jié)了三種模式,遂有此文予以分享。

為了便于理解,以下代碼示例采用的都是 React + rdeco 編寫,設(shè)計模式本身是高度抽象的,并不局限于某一類特定的框架

組件模式

組件模式是我們用的最多的或者說目前大家都唯一能夠理解的模式,組件模式的特點是,予以每個組件獨立的上下文,組件和組件之間有嚴(yán)格的代碼隔離,通常在不考慮全局變量的影響下組件之間是完全無潛在交互的。

const Table = createComponent({
name:'table',
state:{
data:[],
},
view:{
render(){
return(
<div>{this.state.data.map(d=>{
return d
})}<div>
)
}
}
})
const Page = createComponent({
name:'page',
view:{
render(){
return(
<Table />
)
}
}
})
復(fù)制代碼

這種模式我們都很熟悉,Page 和 Table 是兩個擁有獨立上下文的組件,在不同的 UI 框架里有不同的組件交互方式,在 React 中,Page 如果要和 Table 進(jìn)行交互,可以使用 props 傳遞,或者借助 Context 來共享一部分上下文。

但是這種模式在很多場景下并不是完全有效的,只有當(dāng)我們非常明確兩個組件之間的邊界時,模式和實際情況才是相符合的,例如考慮這樣一種場景:

const HeadTitle = ({text})=>{
return(
<p>{text}</p>
)
}
const Page = createComponent({
name:'page',
state:{
text:'page',
},
view:{
render(){
<HeadTtile text={this.state.text}>
}
}
})
復(fù)制代碼

在這個示例中,乍看是沒啥問題,平時我們都會將一些無狀態(tài)的 UI 提取為無狀態(tài)的函數(shù)組件,但經(jīng)過實踐你會發(fā)現(xiàn)實際上,HeadTitle 大概率僅服務(wù)于 Page,也就是說 HeadTitle 并不是為了復(fù)用而被提取,更多是因為大型組件的文件需要拆解從而減小體積,降低管理難度。

但是以此為目的進(jìn)行組件化拆解會破壞原有組件的完整性,導(dǎo)致大量的參數(shù)傳遞,這和我們過度提取代碼到函數(shù)其實是一個效果。

function print(name){
console.log(name)
}
function main(){
const name = 'main'
print(name)
}
// 如果 print 在 main 函數(shù)內(nèi)部則不需要再次傳遞 name
function main(){
const name = 'main'
function print(){
console.log(name)
}
print(name)
}
// 因此對于 main 來說 print 是一個獨立函數(shù)?,還是一個代碼片段?
復(fù)制代碼

為了解決組件提取導(dǎo)致的上下文隔離問題,我們實踐了一種模式,我們稱之為組合模式。

組合模式

和組件模式相比,組合模式是一種輕量化的方案,相比組件模式兩者有明顯的區(qū)別。

  1. 組件模式擁有獨立的上下文,組件和組件之間組合成新的組件需要進(jìn)行上下文的傳遞,而組合模式則只是組件的一個片段,若干個組合體組成了一個完整組件,組合體之間共享上下文,不需要額外傳遞,但組合體本身實現(xiàn)了相關(guān)邏輯的內(nèi)聚。
  2. 組件之間因為上下文隔離,因此可以擁有相同的內(nèi)部成員,組合體只是組件的一個片段,組合體之間不能用相同的內(nèi)部成員。
  3. 有實例,需要命名標(biāo)識,組合體沒有實例,不需要命名標(biāo)識。

參照以上區(qū)別我們來看看的代碼示例:

const table = createCompose({
view:{
renderTable(){
return(
<div>{this.state.data.map(d=>{
return d
})}<div>
)
}
}
})
const head = createCompose({
state:{
text:'page'
},
view:{
renderHead(){
return(
<p>{text}</p>
)
}
}
})
const Page = createComponent(compose({
name:'page',
state:{
data:[]
},
view:{
render(){
<>
{this.view.renderHead()}
{this.view.renderTable()}
</>
}
}
},[table, head]))
復(fù)制代碼

現(xiàn)在 head 和 table 都成了組合體,通過組合變成了 page 的一部分,為此他們可以共享彼此的上下文,而不用額外通過 props 或者 Context 來傳遞或者共享參數(shù)。

除了組合模式,我們還總結(jié)了第三種模式,membrane 模式,這種模式我在早期的文章中有提到過,今天我們將其簡化。

Membrane 模式

和組合模式相比,membrane 模式具有一些共通性,例如同樣沒有獨立的上下文,不需要命名標(biāo)識,不過兩者也有極大的區(qū)別。

  1. membrane 是一種抽象模式,和組合模式相比,每個 membrane 只能有一個模板。
  2. compose 和 membrane 可以聯(lián)合使用。
const pageTemplate = () => {
return {
state:{
name:'',
},
service:{
init(){}
},
controller:{
onMount(){
this.service.init()
}
},
view:{
render(){
return(
<div>{this.state.name}</div>
)
}
}
}
}
const Page1Membrane = createMembrane(pageTemplate(), {
name:'page-1-membrane',
service:{
init(){
this.setter.name('page-1-membrane')
}
}
})
const Page1Membrane = createMembrane(pageTemplate(), {
name:'page-1-membrane',
service:{
init(){
this.setter.name('page-2-membrane')
}
}
})
const Page1 = createComponent(Page1Membrane)
// render Page1 name === page-1-membrane
const Page2 = createComponent(Page2Membrane)
// render Page2 name === page-2-membrane
復(fù)制代碼

如果你熟悉面向?qū)ο笤O(shè)計,那么可能會很快聯(lián)想到 membrane 和 抽象類的特性有些相似,不過相比抽象類,membrane 可以包含具體的實現(xiàn),因此兩者也不完全等價,但是從設(shè)計上是有一定的共通性的

在實際實踐中,我們結(jié)合上述三種模式,借助類似 mermaid 這樣的 UML 圖形庫,在日常迭代中增加了前端設(shè)計相關(guān)的內(nèi)容,從實際結(jié)果看我們認(rèn)為這些模式有助于改善前端設(shè)計的粗糙和非專業(yè)性,同時可以改善前端代碼的標(biāo)準(zhǔn)化程度,利用 UML 圖更好的代替注釋和文字文檔來描述業(yè)務(wù)代碼的組成關(guān)系。

責(zé)任編輯:龐桂玉 來源: web前端營
相關(guān)推薦

2015-09-14 09:31:44

結(jié)對設(shè)計

2022-06-16 08:24:59

設(shè)計模式代碼前端

2022-06-14 10:49:33

代碼優(yōu)化Java

2009-11-06 13:23:27

WCF模式

2020-12-28 10:35:38

前端數(shù)據(jù)技術(shù)

2016-09-13 14:05:24

Spark集群管理模式

2010-06-28 17:43:44

SQL Server

2010-09-09 10:08:59

2024-04-01 08:00:00

MySQL關(guān)聯(lián)設(shè)計數(shù)據(jù)庫

2022-11-03 08:44:24

代理模式Java設(shè)計模式

2022-09-26 08:03:25

VMware虛擬機

2009-12-21 13:37:43

WCF消息交換

2014-09-10 10:07:50

工程師前端工程師

2010-07-13 15:55:12

FTP數(shù)據(jù)傳輸模式

2020-04-23 11:03:09

前端語言開發(fā)

2011-01-18 15:35:59

jQueryJavaScriptweb

2025-04-27 08:40:00

架構(gòu)后臺任務(wù)開發(fā)

2015-06-25 10:23:55

蘋果谷歌

2019-09-02 14:44:15

云計算云安全云取證

2010-10-21 16:43:47

sql server恢
點贊
收藏

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