Go 语言学习:组合,一个对数据结构算法和职场都有提升的设计模式
大家好,我是每周在這里陪你進(jìn)步的網(wǎng)管~,這次我們繼續(xù)設(shè)計(jì)模式的學(xué)習(xí)之旅。本次要學(xué)習(xí)的是組合模式,這個(gè)模式呢,平時(shí)要做業(yè)務(wù)開(kāi)發(fā)的話并不是很常用,但是對(duì)一些特定數(shù)據(jù)結(jié)構(gòu)的處理上卻是少不了它的應(yīng)用。
同時(shí)理解了組合模式的原理后對(duì)你的數(shù)據(jù)結(jié)構(gòu)和算法的提升也是有幫助的,更重要的是能讓你明白一些職場(chǎng)的道理,具體是啥道理呢?看完文章你就明白啦😉。
什么是組合模式
組合模式(Composite Pattern)又叫作部分-整體(Part-Whole)模式,它的宗旨是通過(guò)將單個(gè)對(duì)象(葉子節(jié)點(diǎn))和組合對(duì)象(樹(shù)枝節(jié)點(diǎn))用相同的接口進(jìn)行表示,使得客戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性,屬于結(jié)構(gòu)型設(shè)計(jì)模式。
應(yīng)用場(chǎng)景
組合模式的使用要求業(yè)務(wù)場(chǎng)景中的實(shí)體必須能夠表示成樹(shù)形結(jié)構(gòu)才行,由組合模式將一組對(duì)象組織成樹(shù)形結(jié)構(gòu),客戶端(代碼的使用者)可以將單個(gè)對(duì)象和組合對(duì)象都看做樹(shù)中的節(jié)點(diǎn),以統(tǒng)一處理邏輯,并且利用樹(shù)形結(jié)構(gòu)的特點(diǎn),將對(duì)樹(shù)、子樹(shù)的處理轉(zhuǎn)化成葉節(jié)點(diǎn)的遞歸處理,依次簡(jiǎn)化代碼實(shí)現(xiàn)。
通過(guò)上邊的描述我們可以馬上想到文件系統(tǒng)、公司組織架構(gòu)這些有層級(jí)結(jié)構(gòu)的事物的操作會(huì)更適合應(yīng)用組合模式。
組合模式的結(jié)構(gòu)
組合模式由以下幾個(gè)角色構(gòu)成:
組件 (Component): 組件是一個(gè)接口,描述了樹(shù)中單個(gè)對(duì)象和組合對(duì)象都要實(shí)現(xiàn)的的操作。
葉節(jié)點(diǎn) (Leaf) :即單個(gè)對(duì)象節(jié)點(diǎn),是樹(shù)的基本結(jié)構(gòu),它不包含子節(jié)點(diǎn),因此也就無(wú)法將工作指派給下去,葉節(jié)點(diǎn)最終會(huì)完成大部分的實(shí)際工作。
組合對(duì)象 (Composite)”—— 是包含葉節(jié)點(diǎn)或其他組合對(duì)象等子項(xiàng)目的符合對(duì)象。組合對(duì)象不知道其子項(xiàng)目所屬的具體類(lèi),它只通過(guò)通用的組件接口與其子項(xiàng)目交互。
客戶端 (Client): 通過(guò)組件接口與所有項(xiàng)目交互。因此,客戶端能以相同方式與樹(shù)狀結(jié)構(gòu)中的簡(jiǎn)單或復(fù)雜對(duì)象進(jìn)行交互。
組合模式代碼實(shí)現(xiàn)
下面用一個(gè)公司組織架構(gòu)的例子來(lái)演示下用代碼怎么實(shí)現(xiàn)組合模式。
我們都知道大公司的組織架構(gòu)會(huì)很復(fù)雜,往往是由集團(tuán)總公司--> 分公司,每個(gè)層級(jí)的公司還有不同的部門(mén),比如說(shuō)總公司有財(cái)務(wù)部,分公司也會(huì)有。分公司偏傳統(tǒng)一點(diǎn),在互聯(lián)網(wǎng)大廠有可能會(huì)按 BG、BU 這樣分,不過(guò)在展示層級(jí)結(jié)構(gòu)上意思都一樣。
咱們來(lái)看下這個(gè)例子,使用的是 Go 語(yǔ)言的代碼來(lái)實(shí)現(xiàn)組合模式。首先我們定義一個(gè)組織的行為接口,這個(gè)接口大到總公司小到一個(gè)部門(mén)都得實(shí)現(xiàn):
//表示組織機(jī)構(gòu)的接口
typeOrganizationinterface{
display()
duty()
}
這里為了簡(jiǎn)單演示,接口里就提供兩個(gè)方法,一個(gè)是打印出自己的組織結(jié)構(gòu)的方法 display () 另外一個(gè)是展示組織職責(zé)的方法 duty ()。接下來(lái)定義和實(shí)現(xiàn)組合對(duì)象的行為:
//組合對(duì)象--上級(jí)部門(mén)
"本文使用的完整可運(yùn)行源碼
去公眾號(hào)「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"
typeCompositeOrganizationstruct{
orgNamestring
depthint
list[]Organization
}
funcNewCompositeOrganization(namestring,depthint)*CompositeOrganization{
return&CompositeOrganization{name,depth,[]Organization{}}
}
func(c*CompositeOrganization)add(orgOrganization){
ifc==nil{
return
}
c.list=end(c.list,org)
}
func(c*CompositeOrganization)remove(orgOrganization){
ifc==nil{
return
}
fori,val:=rangec.list{
ifval==org{
c.list=end(c.list[:i],c.list[i+1:]...)
return
}
}
return
}
func(c*CompositeOrganization)display(){
ifc==nil{
return
}
fmt.Println(strings.Repeat("-",c.depth*2),"",c.orgName)
for_,val:=rangec.list{
val.display()
}
}
func(c*CompositeOrganization)duty(){
ifc==nil{
return
}
for_,val:=rangec.list{
val.duty()
}
}
組合對(duì)象用來(lái)表示有下屬部門(mén)的組織,在代碼里可以看到,它持有一個(gè) [] Organization 類(lèi)型的列表,這里存放的是它的下屬組織。組合對(duì)象的 display、duty 這兩個(gè)方法的實(shí)現(xiàn)完全就是把工作委托給他們的下屬組織來(lái)做的,這也是組合模式的特點(diǎn)。
下面我們?cè)賮?lái)看兩個(gè)職能部門(mén)人力資源和財(cái)務(wù)部門(mén)的類(lèi)型實(shí)現(xiàn)。
//Leaf對(duì)象--人力資源部門(mén)
"本文使用的完整可運(yùn)行源碼
去公眾號(hào)「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"
typeHRDOrgstruct{
orgNamestring
depthint
}
func(o*HRDOrg)display(){
ifo==nil{
return
}
fmt.Println(strings.Repeat("-",o.depth*2),"",o.orgName)
}
func(o*HRDOrg)duty(){
ifo==nil{
return
}
fmt.Println(o.orgName,"員工招聘培訓(xùn)管理")
}
//Leaf對(duì)象--財(cái)務(wù)部門(mén)
typeFinanceOrgstruct{
orgNamestring
depthint
}
func(f*FinanceOrg)display(){
iff==nil{
return
}
fmt.Println(strings.Repeat("-",f.depth*2),"",f.orgName)
}
func(f*FinanceOrg)duty(){
iff==nil{
return
}
fmt.Println(f.orgName,"員工招聘培訓(xùn)管理")
}
只要我們?cè)诳蛻舳酥薪M合好組織架構(gòu)的結(jié)構(gòu),不管有幾層組織,客戶端對(duì)整個(gè)組織的調(diào)用是不會(huì)改變的。
funcmain(){
root:=NewCompositeOrganization("北京總公司",1)
root.add(&HRDOrg{orgName:"總公司人力資源部",depth:2})
root.add(&FinanceOrg{orgName:"總公司財(cái)務(wù)部",depth:2})
compSh:=NewCompositeOrganization("上海分公司",2)
compSh.add(&HRDOrg{orgName:"上海分公司人力資源部",depth:3})
compSh.add(&FinanceOrg{orgName:"上海分公司財(cái)務(wù)部",depth:3})
root.add(compSh)
compGd:=NewCompositeOrganization("廣東分公司",2)
compGd.add(&HRDOrg{orgName:"廣東分公司人力資源部",depth:3})
compGd.add(&FinanceOrg{orgName:"南京辦事處財(cái)務(wù)部",depth:3})
root.add(compGd)
fmt.Println("公司組織架構(gòu):")
root.display()
fmt.Println("各組織的職責(zé):")
root.duty()
}
組合模式和上一節(jié)我們學(xué)的裝飾器模式在結(jié)構(gòu)上挺像的,下面我們來(lái)說(shuō)說(shuō)他們的區(qū)別。
組合和裝飾器的區(qū)別
組合模式和裝飾器模式在結(jié)構(gòu)上很像,擁有非常相似的類(lèi)結(jié)構(gòu)(相似到組合模式的類(lèi)圖就是我 Copy 裝飾器模式改了下方法名字......)。但是兩者在使用意圖上是有區(qū)別的。
組合模式:為葉子對(duì)象和組合對(duì)象提供了統(tǒng)一的接口,葉子對(duì)象分擔(dān)組合對(duì)象要做的工作。其實(shí)組合對(duì)象就是派了下活兒,等下面的干完后,它再給上層調(diào)用者返(匯)回(報(bào)),類(lèi)似于公司里的那些組合 *。
裝飾器模式:裝飾器屬于大哥帶小弟的類(lèi)型,核心的活兒是小弟干的(小弟就是被裝飾的對(duì)象)但是各位大哥會(huì)幫你做好干活兒之外的事兒,比如公司你在公司里的 Mentor、項(xiàng)目經(jīng)理、領(lǐng)導(dǎo)們干的事兒就是給在給你做增強(qiáng),你可以把他們理解成是你的裝飾器😉。
說(shuō)點(diǎn)題外話,如果你的 Mentor、領(lǐng)導(dǎo)沒(méi)有給你做增強(qiáng),那當(dāng)初他們給你定級(jí) P7 是高于你面試的水平的。是希望進(jìn)來(lái)后你能夠拼一把,快速成長(zhǎng)起來(lái)。P7 這個(gè)層級(jí),不是把事情做好就可以的。你需要有體系化思考的能力,它的價(jià)值點(diǎn)在哪里,你是否做出了壁壘形成了核心競(jìng)爭(zhēng)力,是否沉淀了一套可復(fù)用的物理資料和方法論?...... (字兒太多了,完整版請(qǐng)自行搜索)
總結(jié)
組合模式的優(yōu)點(diǎn)主要有以下兩點(diǎn)
實(shí)現(xiàn)類(lèi)似樹(shù)形結(jié)構(gòu),可以清楚地定義各層次的復(fù)雜對(duì)象,表示對(duì)象的全部或部分層次。
簡(jiǎn)化了客戶端代碼,讓客戶端忽略了層次的差異,方便對(duì)整個(gè)層次結(jié)構(gòu)進(jìn)行控制。
實(shí)際上,組合模式與其說(shuō)是一種設(shè)計(jì)模式,倒不如說(shuō)是對(duì)業(yè)務(wù)場(chǎng)景的一種數(shù)據(jù)結(jié)構(gòu)和算法的抽象,場(chǎng)景中的數(shù)據(jù)可以表示成樹(shù)這種結(jié)構(gòu),業(yè)務(wù)需求的邏輯可以通過(guò)對(duì)樹(shù)的遞歸遍歷算法實(shí)現(xiàn)。
本文來(lái)自微信公眾號(hào):網(wǎng)管叨 bi 叨 (ID:kevin_tech),作者:KevinYan11
總結(jié)
以上是生活随笔為你收集整理的Go 语言学习:组合,一个对数据结构算法和职场都有提升的设计模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《消逝的光芒 2》Steam 永久降价:
- 下一篇: 作家百态之二:山南海北