0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

GoF設(shè)計(jì)模式之迭代器模式

元閏子的邀請(qǐng) ? 來源:元閏子的邀請(qǐng) ? 作者:元閏子的邀請(qǐng) ? 2022-08-01 11:22 ? 次閱讀

上一篇:【Go實(shí)現(xiàn)】實(shí)踐GoF的23種設(shè)計(jì)模式:觀察者模式

簡單的分布式應(yīng)用系統(tǒng)(示例代碼工程):https://github.com/ruanrunxue/Practice-Design-Pattern--Go-Implementation

簡介

有時(shí)會(huì)遇到這樣的需求,開發(fā)一個(gè)模塊,用于保存對(duì)象;不能用簡單的數(shù)組、列表,得是紅黑樹、跳表等較為復(fù)雜的數(shù)據(jù)結(jié)構(gòu);有時(shí)為了提升存儲(chǔ)效率或持久化,還得將對(duì)象序列化;但必須給客戶端提供一個(gè)易用的 API允許方便地、多種方式地遍歷對(duì)象,絲毫不察覺背后的數(shù)據(jù)結(jié)構(gòu)有多復(fù)雜。

346ff082-1143-11ed-ba43-dac502259ad0.jpg

對(duì)這樣的 API,很適合使用迭代器模式Iterator Pattern)實(shí)現(xiàn)。

GoF 對(duì) 迭代器模式 的定義如下:

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

從描述可知,迭代器模式主要用在訪問對(duì)象集合的場(chǎng)景,能夠向客戶端隱藏集合的實(shí)現(xiàn)細(xì)節(jié)

Java 的 Collection 家族、C++ 的 STL 標(biāo)準(zhǔn)庫,都是使用迭代器模式的典范,它們?yōu)榭蛻舳颂峁┝撕唵我子玫?API,并且能夠根據(jù)業(yè)務(wù)需要實(shí)現(xiàn)自己的迭代器,具備很好的可擴(kuò)展性。

UML 結(jié)構(gòu)

34994266-1143-11ed-ba43-dac502259ad0.jpg

場(chǎng)景上下文

在簡單的分布式應(yīng)用系統(tǒng)(示例代碼工程)中,db 模塊用來存儲(chǔ)服務(wù)注冊(cè)和監(jiān)控信息,它的主要接口如下:

//demo/db/db.go
packagedb
//Db數(shù)據(jù)庫抽象接口
typeDbinterface{
CreateTable(t*Table)error
CreateTableIfNotExist(t*Table)error
DeleteTable(tableNamestring)error

Query(tableNamestring,primaryKeyinterface{},resultinterface{})error
Insert(tableNamestring,primaryKeyinterface{},recordinterface{})error
Update(tableNamestring,primaryKeyinterface{},recordinterface{})error
Delete(tableNamestring,primaryKeyinterface{})error

...
}

從增刪查改接口可以看出,它是一個(gè) key-value 數(shù)據(jù)庫,另外,為了提供類似關(guān)系型數(shù)據(jù)庫的按列查詢能力,我們又抽象出Table對(duì)象:

//demo/db/table.go
packagedb
//Table數(shù)據(jù)表定義
typeTablestruct{
namestring
recordTypereflect.Type
recordsmap[interface{}]record
}

其中,Table底層用map存儲(chǔ)對(duì)象數(shù)據(jù),但并沒有存儲(chǔ)對(duì)象本身,而是從對(duì)象轉(zhuǎn)換而成的recordrecord的實(shí)現(xiàn)原理是利用反射機(jī)制,將對(duì)象的屬性名 field 和屬性值 value 分開存儲(chǔ),以此支持按列查詢能力(一類對(duì)象可以類比為一張表):

//demo/db/record.go
packagedb

typerecordstruct{
primaryKeyinterface{}
fieldsmap[string]int//key為屬性名,value屬性值的索引
values[]interface{}//存儲(chǔ)屬性值
}
//從對(duì)象轉(zhuǎn)換成record
funcrecordFrom(keyinterface{},valueinterface{})(rrecord,eerror){
...//異常處理
vType:=reflect.TypeOf(value)
vVal:=reflect.ValueOf(value)
ifvVal.Type().Kind()==reflect.Pointer{
vType=vType.Elem()
vVal=vVal.Elem()
}
record:=record{
primaryKey:key,
fields:make(map[string]int,vVal.NumField()),
values:make([]interface{},vVal.NumField()),
}
fori:=0;ireturnrecord,nil
}

當(dāng)然,客戶端并不會(huì)察覺 db 模塊背后的復(fù)雜機(jī)制,它們直接使用的仍是對(duì)象:

typetestRegionstruct{
Idint
Namestring
}
funcclient(){
mdb:=db.MemoryDbInstance()
tableName:="testRegion"
table:=NewTable(tableName).WithType(reflect.TypeOf(new(testRegion)))
mdb.CreateTable(table)
mdb.Insert(tableName,"region1",&testRegion{Id:0,Name:"region-1"})
result:=new(testRegion)
mdb.Query(tableName,"region1",result)
}
34ad92b6-1143-11ed-ba43-dac502259ad0.jpg

另外,除了上述按 Key 查詢接口,我們還想提供全表查詢接口,有隨機(jī)和有序 2 種表記錄遍歷方式,并且支持客戶端自己擴(kuò)展遍歷方式。下面使用迭代器模式來實(shí)現(xiàn)該需求。

代碼實(shí)現(xiàn)

這里并沒有按照標(biāo)準(zhǔn)的 UML 結(jié)構(gòu)去實(shí)現(xiàn),而是結(jié)合工廠方法模式來解決公共代碼的復(fù)用問題:

34c41cc0-1143-11ed-ba43-dac502259ad0.jpg
//demo/db/table_iterator.go
packagedb

//關(guān)鍵點(diǎn)1:定義迭代器抽象接口,允許后續(xù)客戶端擴(kuò)展遍歷方式
//TableIterator表迭代器接口
typeTableIteratorinterface{
HasNext()bool
Next(nextinterface{})error
}

//關(guān)鍵點(diǎn)2:定義迭代器接口的實(shí)現(xiàn)
//tableIteratorImpl迭代器接口公共實(shí)現(xiàn)類
typetableIteratorImplstruct{
//關(guān)鍵點(diǎn)3:定義一個(gè)集合存儲(chǔ)待遍歷的記錄,這里的記錄已經(jīng)排序好或者隨機(jī)打散
records[]record
//關(guān)鍵點(diǎn)4:定義一個(gè)cursor游標(biāo)記錄當(dāng)前遍歷的位置
cursorint
}

//關(guān)鍵點(diǎn)5:在HasNext函數(shù)中的判斷是否已經(jīng)遍歷完所有記錄
func(r*tableIteratorImpl)HasNext()bool{
returnr.cursorlen(r.records)
}

//關(guān)鍵點(diǎn)6:在Next函數(shù)中取出下一個(gè)記錄,并轉(zhuǎn)換成客戶端期望的對(duì)象類型,記得增加cursor
func(r*tableIteratorImpl)Next(nextinterface{})error{
record:=r.records[r.cursor]
r.cursor++
iferr:=record.convertByValue(next);err!=nil{
returnerr
}
returnnil
}

//關(guān)鍵點(diǎn)7:通過工廠方法模式,完成不同類型的迭代器對(duì)象創(chuàng)建
//TableIteratorFactory表迭代器工廠
typeTableIteratorFactoryinterface{
Create(table*Table)TableIterator
}

//隨機(jī)迭代器
typerandomTableIteratorFactorystruct{}
func(r*randomTableIteratorFactory)Create(table*Table)TableIterator{
varrecords[]record
for_,r:=rangetable.records{
records=append(records,r)
}
rand.Seed(time.Now().UnixNano())
rand.Shuffle(len(records),func(i,jint){
records[i],records[j]=records[j],records[i]
})
return&tableIteratorImpl{
records:records,
cursor:0,
}
}

//有序迭代器
//Comparator如果i
typeComparatorfunc(i,jinterface{})bool
//sortedTableIteratorFactory根據(jù)主鍵進(jìn)行排序,排序邏輯由Comparator定義
typesortedTableIteratorFactorystruct{
comparatorComparator
}
func(s*sortedTableIteratorFactory)Create(table*Table)TableIterator{
varrecords[]record
for_,r:=rangetable.records{
records=append(records,r)
}
sort.Sort(newRecords(records,s.comparator))
return&tableIteratorImpl{
records:records,
cursor:0,
}
}

最后,為Table對(duì)象引入TableIterator

//demo/db/table.go

//Table數(shù)據(jù)表定義
typeTablestruct{
namestring
recordTypereflect.Type
recordsmap[interface{}]record
//關(guān)鍵點(diǎn)8:持有迭代器工廠方法接口
iteratorFactoryTableIteratorFactory//默認(rèn)使用隨機(jī)迭代器
}
//關(guān)鍵點(diǎn)9:定義Setter方法,提供迭代器工廠的依賴注入
func(t*Table)WithTableIteratorFactory(iteratorFactoryTableIteratorFactory)*Table{
t.iteratorFactory=iteratorFactory
returnt
}
//關(guān)鍵點(diǎn)10:定義創(chuàng)建迭代器的接口,其中調(diào)用迭代器工廠完成實(shí)例化
func(t*Table)Iterator()TableIterator{
returnt.iteratorFactory.Create(t)
}

客戶端這樣使用:

funcclient(){
table:=NewTable("testRegion").WithType(reflect.TypeOf(new(testRegion))).
WithTableIteratorFactory(NewSortedTableIteratorFactory(regionIdComparator))
iter:=table.Iterator()
foriter.HashNext(){
next:=new(testRegion)
err:=iter.Next(next)
...
}
}

總結(jié)實(shí)現(xiàn)迭代器模式的幾個(gè)關(guān)鍵點(diǎn):

  1. 定義迭代器抽象接口,目的是提供客戶端自擴(kuò)展能力,通常包含HashNext()Next()兩個(gè)方法,上述例子為TableIterator。
  2. 定義迭代器接口的實(shí)現(xiàn)類,上述例子為tableIteratorImpl,這里主要起到了 Java/C++ 等帶繼承特性語言中,基類的作用,目的是復(fù)用代碼。
  3. 在實(shí)現(xiàn)類中持有待遍歷的記錄集合,通常是已經(jīng)排序好或隨機(jī)打散后的,上述例子為tableIteratorImpl.records。
  4. 在實(shí)現(xiàn)類中持有游標(biāo)值,記錄當(dāng)前遍歷的位置,上述例子為tableIteratorImpl.cursor
  5. HashNext()方法中判斷是否已經(jīng)遍歷完所有記錄。
  6. Next()方法中取出下一個(gè)記錄,并轉(zhuǎn)換成客戶端期望的對(duì)象類型,取完后增加游標(biāo)值。
  7. 通過工廠方法模式,完成不同類型的迭代器對(duì)象創(chuàng)建,上述例子為TableIteratorFactory接口,以及它的實(shí)現(xiàn),randomTableIteratorFactorysortedTableIteratorFactory
  8. 在待遍歷的對(duì)象中,持有迭代器工廠方法接口,上述例子為Table.iteratorFactory。
  9. 為對(duì)象定義 Setter 方法,提供迭代器工廠的依賴注入,上述例子為Table.WithTableIteratorFactory()方法。
  10. 為對(duì)象定義創(chuàng)建迭代器的接口,上述例子為Table.Iterator()方法。

其中,7~9 步是結(jié)合工廠方法模式實(shí)現(xiàn)時(shí)的特有步驟,如果你的迭代器實(shí)現(xiàn)中沒有用到工廠方法模式,可以省略這幾步。

擴(kuò)展

Go 風(fēng)格的實(shí)現(xiàn)

前面的實(shí)現(xiàn),是典型的面向?qū)ο箫L(fēng)格,下面以隨機(jī)迭代器為例,給出一個(gè) Go 風(fēng)格的實(shí)現(xiàn):

//demo/db/table_iterator_closure.go
packagedb

//關(guān)鍵點(diǎn)1:定義HasNext和Next函數(shù)類型
typeHasNextfunc()bool
typeNextfunc(interface{})error

//關(guān)鍵點(diǎn)2:定義創(chuàng)建迭代器的方法,返回HashNext和Next函數(shù)
func(t*Table)ClosureIterator()(HasNext,Next){
varrecords[]record
for_,r:=ranget.records{
records=append(records,r)
}
rand.Seed(time.Now().UnixNano())
rand.Shuffle(len(records),func(i,jint){
records[i],records[j]=records[j],records[i]
})
size:=len(records)
cursor:=0
//關(guān)鍵點(diǎn)3:在迭代器創(chuàng)建方法定義HasNext和Next的實(shí)現(xiàn)邏輯
hasNext:=func()bool{
returncursorfunc(nextinterface{})error{
record:=records[cursor]
cursor++
iferr:=record.convertByValue(next);err!=nil{
returnerr
}
returnnil
}
returnhasNext,next
}

客戶端這樣用:

funcclient(){
table:=NewTable("testRegion").WithType(reflect.TypeOf(new(testRegion))).
WithTableIteratorFactory(NewSortedTableIteratorFactory(regionIdComparator))
hasNext,next:=table.ClosureIterator()
forhasNext(){
result:=new(testRegion)
err:=next(result)
...
}
}

Go 風(fēng)格的實(shí)現(xiàn),利用了函數(shù)閉包的特點(diǎn),把原本在迭代器實(shí)現(xiàn)的邏輯,放到了迭代器創(chuàng)建方法上。相比面向?qū)ο箫L(fēng)格,省掉了迭代器抽象接口和實(shí)現(xiàn)對(duì)象的定義,看起來更加的簡潔。

總結(jié)幾個(gè)實(shí)現(xiàn)關(guān)鍵點(diǎn):

  1. 聲明HashNextNext的函數(shù)類型,等同于迭代器抽象接口的作用。
  2. 定義迭代器創(chuàng)建方法,返回類型為HashNextNext,上述例子為ClosureIterator()方法。
  3. 在迭代器創(chuàng)建方法內(nèi),定義HasNextNext的具體實(shí)現(xiàn),利用函數(shù)閉包來傳遞狀態(tài)(recordscursor)。

基于 channel 的實(shí)現(xiàn)

我們還能基于 Go 語言中的 channel 來實(shí)現(xiàn)迭代器模式,因?yàn)榍拔牡?db 模塊應(yīng)用場(chǎng)景并不適用,所以另舉一個(gè)簡單的例子:

typeRecordint

func(r*Record)doSomething(){
//...
}

typeComplexCollectionstruct{
records[]Record
}

//關(guān)鍵點(diǎn)1:定義迭代器創(chuàng)建方法,返回只能接收的channel類型
func(c*ComplexCollection)Iterator()<-chanRecord{
//關(guān)鍵點(diǎn)2:創(chuàng)建一個(gè)無緩沖的channel
ch:=make(chanRecord)
//關(guān)鍵點(diǎn)3:另起一個(gè)goroutine往channel寫入記錄,如果接收端還沒開始接收,會(huì)阻塞住
gofunc(){
for_,record:=rangec.records{
ch<-?record
????????}
????//關(guān)鍵點(diǎn)4:寫完后,關(guān)閉channel
close(ch)
}()
returnch
}

客戶端這樣使用:

funcclient(){
collection:=NewComplexCollection()
//關(guān)鍵點(diǎn)5:使用時(shí),直接通過for-range來遍歷channel讀取記錄
forrecord:=rangecollection.Iterator(){
record.doSomething()
}
}

總結(jié)實(shí)現(xiàn)基于 channel 的迭代器模式的幾個(gè)關(guān)鍵點(diǎn):

  1. 定義迭代器創(chuàng)建方法,返回一個(gè)只能接收的 channel。
  2. 在迭代器創(chuàng)建方法中,定義一個(gè)無緩沖的 channel。
  3. 另起一個(gè) goroutine 往 channel 中寫入記錄。如果接收端沒有接收,會(huì)阻塞住。
  4. 寫完后,關(guān)閉 channel。
  5. 客戶端使用時(shí),直接通過 for-range 遍歷 channel 讀取記錄即可。

帶有 callback 函數(shù)的實(shí)現(xiàn)

還可以在創(chuàng)建迭代器時(shí),傳入一個(gè) callback 函數(shù),在迭代器返回記錄前,先調(diào)用 callback 函數(shù)對(duì)記錄進(jìn)行一些操作。

比如,在基于 channel 的實(shí)現(xiàn)例子中,可以增加一個(gè) callback 函數(shù),將每個(gè)記錄打印出來:

//關(guān)鍵點(diǎn)1:聲明callback函數(shù)類型,以Record作為入?yún)?/span>
typeCallbackfunc(record*Record)
//關(guān)鍵點(diǎn)2:定義具體的callback函數(shù)
funcPrintRecord(record*Record){
fmt.Printf("%+v
",record)
}
//關(guān)鍵點(diǎn)3:定義以callback函數(shù)作為入?yún)⒌牡鲃?chuàng)建方法
func(c*ComplexCollection)Iterator(callbackCallback)<-chanRecord{
ch:=make(chanRecord)
gofunc(){
for_,record:=rangec.records{
//關(guān)鍵點(diǎn)4:遍歷記錄時(shí),調(diào)用callback函數(shù)作用在每條記錄上
callback(&record)
ch<-?record
????????}
????????close(ch)
}()
returnch
}

funcclient(){
collection:=NewComplexCollection()
//關(guān)鍵點(diǎn)5:創(chuàng)建迭代器時(shí),傳入具體的callback函數(shù)
forrecord:=rangecollection.Iterator(PrintRecord){
record.doSomething()
}
}

總結(jié)實(shí)現(xiàn)帶有 callback 的迭代器模式的幾個(gè)關(guān)鍵點(diǎn):

  1. 聲明 callback 函數(shù)類型,以 Record 作為入?yún)ⅰ?/li>
  2. 定義具體的 callback 函數(shù),比如上述例子中打印記錄的PrintRecord函數(shù)。
  3. 定義迭代器創(chuàng)建方法,以 callback 函數(shù)作為入?yún)ⅰ?/li>
  4. 迭代器內(nèi),遍歷記錄時(shí),調(diào)用 callback 函數(shù)作用在每條記錄上。
  5. 客戶端創(chuàng)建迭代器時(shí),傳入具體的 callback 函數(shù)。

典型應(yīng)用場(chǎng)景

  • 對(duì)象集合/存儲(chǔ)類模塊,并希望向客戶端隱藏模塊背后的復(fù)雜數(shù)據(jù)結(jié)構(gòu)。

  • 希望支持客戶端自擴(kuò)展多種遍歷方式。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 隱藏模塊背后復(fù)雜的實(shí)現(xiàn)機(jī)制,為客戶端提供一個(gè)簡單易用的接口。

  • 支持?jǐn)U展多種遍歷方式,具備較強(qiáng)的可擴(kuò)展性,符合開閉原則。

  • 遍歷算法和數(shù)據(jù)存儲(chǔ)分離,符合單一職責(zé)原則。

缺點(diǎn)

  • 容易濫用,比如給簡單的集合類型實(shí)現(xiàn)迭代器接口,反而使代碼更復(fù)雜。
  • 相比于直接遍歷集合,迭代器效率要更低一些,因?yàn)樯婕暗礁鄬?duì)象的創(chuàng)建,以及可能的對(duì)象拷貝。
  • 需要時(shí)刻注意在迭代器遍歷過程中,由原始集合發(fā)生變更引發(fā)的并發(fā)問題。一種解決方法是,在創(chuàng)建迭代器時(shí),拷貝一份原始數(shù)據(jù)(TableIterator就這么實(shí)現(xiàn)),但存在效率低、內(nèi)存占用大的問題。

與其他模式的關(guān)聯(lián)

迭代器模式通常會(huì)與工廠方法模式一起使用,如前文實(shí)現(xiàn)。

文章配圖

可以在用Keynote畫出手繪風(fēng)格的配圖中找到文章的繪圖方法。

審核編輯:湯梓紅


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 設(shè)計(jì)模式
    +關(guān)注

    關(guān)注

    0

    文章

    53

    瀏覽量

    8616
  • 迭代器
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    4289

原文標(biāo)題:【Go實(shí)現(xiàn)】實(shí)踐GoF的23種設(shè)計(jì)模式:迭代器模式

文章出處:【微信號(hào):yuanrunzi,微信公眾號(hào):元閏子的邀請(qǐng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    談?wù)凱ython 中的迭代模式

    年,Design Patterns - Elements of Reusable Object-Oriented Software)中,它提出了23種設(shè)計(jì)模式迭代模式就是其中的一種
    發(fā)表于 11-23 13:10 ?746次閱讀
    談?wù)凱ython 中的<b class='flag-5'>迭代</b><b class='flag-5'>器</b><b class='flag-5'>模式</b>

    關(guān)于國產(chǎn)MCU GOF32F103C8T6 軟硬件通用

    GOF32F103X8和GOF32F103XB標(biāo)準(zhǔn)型MCU系列使用高性能的ARM Cortex-M3 32 位的RISC內(nèi)核,工作頻率為72MHz,內(nèi)置高速存儲(chǔ)(高達(dá)128K字節(jié)的閃存和20K字節(jié)
    發(fā)表于 04-19 09:50

    Command模式與動(dòng)態(tài)語言

    Gof的設(shè)計(jì)模式中,有一個(gè)模式引起的爭議比較大,有很多人甚至認(rèn)為這個(gè)模式應(yīng)該排除在OO模式之外,原因在于它不具有OO的特性
    發(fā)表于 06-22 10:20 ?944次閱讀
    Command<b class='flag-5'>模式</b>與動(dòng)態(tài)語言

    Modbus ASCII 模式通訊程序

    C語言編寫的臺(tái)達(dá)變頻Modbus ASCII 模式通訊程序
    發(fā)表于 12-02 10:25 ?6次下載

    Proteus定時(shí)_計(jì)數(shù)0的CTC模式應(yīng)用

    Proteus定時(shí)_計(jì)數(shù)0的CTC模式應(yīng)用,很好的Proteus了,快來下載不學(xué)習(xí)吧。
    發(fā)表于 04-18 15:34 ?0次下載

    Proteus定時(shí)_計(jì)數(shù)0的快速PWM模式應(yīng)用

    Proteus定時(shí)_計(jì)數(shù)0的快速PWM模式應(yīng)用,很好的Proteus了,快來下載不學(xué)習(xí)吧
    發(fā)表于 04-18 15:34 ?0次下載

    Proteus定時(shí)_計(jì)數(shù)1的CTC模式應(yīng)用

    Proteus定時(shí)_計(jì)數(shù)1的CTC模式應(yīng)用,很好的Proteus了,快來下載不學(xué)習(xí)吧。
    發(fā)表于 04-18 15:34 ?0次下載

    Proteus定時(shí)_計(jì)數(shù)2的CTC模式應(yīng)用

    Proteus定時(shí)_計(jì)數(shù)2的CTC模式應(yīng)用,很好的Proteus了,快來下載不學(xué)習(xí)吧。
    發(fā)表于 04-18 15:34 ?0次下載

    算法與數(shù)據(jù)結(jié)構(gòu)——迭代模式

    第三章為算法與數(shù)據(jù)結(jié)構(gòu),本文為3.4 迭代模式。
    的頭像 發(fā)表于 09-20 17:09 ?4845次閱讀
    算法與數(shù)據(jù)結(jié)構(gòu)——<b class='flag-5'>迭代</b><b class='flag-5'>器</b><b class='flag-5'>模式</b>

    嵌入式軟件設(shè)計(jì)設(shè)計(jì)模式

    文章目錄前言1.設(shè)計(jì)模式適配器模式2.設(shè)計(jì)模式單例模式3.設(shè)計(jì)
    發(fā)表于 10-21 11:07 ?9次下載
    嵌入式軟件設(shè)計(jì)<b class='flag-5'>之</b>設(shè)計(jì)<b class='flag-5'>模式</b>

    GoF設(shè)計(jì)模式訪問者模式

    訪問者模式的目的是,解耦數(shù)據(jù)結(jié)構(gòu)和算法,使得系統(tǒng)能夠在不改變現(xiàn)有代碼結(jié)構(gòu)的基礎(chǔ)上,為對(duì)象新增一種新的操作。
    的頭像 發(fā)表于 10-08 11:05 ?603次閱讀

    GoF設(shè)計(jì)模式代理模式

    它是一個(gè)使用率非常高的設(shè)計(jì)模式,在現(xiàn)實(shí)生活中,也是很常見。比如,演唱會(huì)門票黃牛。假設(shè)你需要看一場(chǎng)演唱會(huì),但官網(wǎng)上門票已經(jīng)售罄,于是就當(dāng)天到現(xiàn)場(chǎng)通過黃牛高價(jià)買了一張。在這個(gè)例子中,黃牛就相當(dāng)于演唱會(huì)門票的代理,在正式渠道無法購買門票的情況下,你通過代理完成了該目標(biāo)。
    的頭像 發(fā)表于 10-17 09:45 ?802次閱讀

    迭代模式在UVM中的應(yīng)用有哪些

    行為型設(shè)計(jì)模式數(shù)量較多,上一篇介紹了模板模式和策略模式,下面對(duì)迭代模式進(jìn)行介紹,挖掘其在UVM中的應(yīng)用。
    的頭像 發(fā)表于 08-14 17:15 ?516次閱讀
    <b class='flag-5'>迭代</b><b class='flag-5'>模式</b>在UVM中的應(yīng)用有哪些

    實(shí)踐GoF的23種設(shè)計(jì)模式:備忘錄模式

    相對(duì)于代理模式、工廠模式等設(shè)計(jì)模式,備忘錄模式(Memento)在我們?nèi)粘i_發(fā)中出鏡率并不高,除了應(yīng)用場(chǎng)景的限制之外,另一個(gè)原因,可能是備忘錄模式
    的頭像 發(fā)表于 11-25 09:05 ?445次閱讀
    實(shí)踐<b class='flag-5'>GoF</b>的23種設(shè)計(jì)<b class='flag-5'>模式</b>:備忘錄<b class='flag-5'>模式</b>

    實(shí)踐GoF的23種設(shè)計(jì)模式:解釋模式

    解釋模式(Interpreter Pattern)應(yīng)該是 GoF 的 23 種設(shè)計(jì)模式中使用頻率最少的一種了,它的應(yīng)用場(chǎng)景較為局限。
    的頭像 發(fā)表于 04-01 11:01 ?485次閱讀
    實(shí)踐<b class='flag-5'>GoF</b>的23種設(shè)計(jì)<b class='flag-5'>模式</b>:解釋<b class='flag-5'>器</b><b class='flag-5'>模式</b>