91在线一级黄片|91视频在线观看18|成人夜间呦呦网站|91资源欧美日韩超碰|久久最新免费精品视频一区二区三区|国产探花视频在线观看|黄片真人免费三级片毛片|国产人无码视频在线|精品成人影视无码三区|久久视频爱久久免费精品

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Go開源庫、大項目的公共包,是這么用建造者模式的

建造者模式,也有翻譯成生成器模式的,大家看到后知道他們是一個東西,都是Builer Pattern翻譯過來的就行。它是一種對象構(gòu)建模式,是將一個復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 那么什么情況下適合使用建造模式呢?

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、重慶小程序開發(fā)、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了城區(qū)免費建站歡迎大家使用!

  • 當(dāng)要構(gòu)建的對象很大并且需要多個步驟時,使用構(gòu)建器模式,有助于減小構(gòu)造函數(shù)的大小。

我們先來看下其他語言里的 Builder,再看看 Go 怎么使用,進行個對比。

Java 的Builder

如果你是寫過Java程序一定對下面這類代碼很熟悉。

Coffee.builder().name("Latti").price("30").build()

當(dāng)然,自己給Coffee類加上構(gòu)建模式,還是需要寫不少額外的代碼,得給 Coffee 類加一個靜態(tài)內(nèi)部類 CoffeeBuilder,用CoffeeBuilder,去建造Coffee類的對象。

類、靜態(tài)內(nèi)部類傻傻分不清?可以看下小弟的 Java 文

光會面向?qū)ο蠡A(chǔ)做不了項目,還得掌握這些進階知識

不過Java?里有一個lombok?包,只要引入這個包再在實體類加上@Builder注解,就可以使用建造模式構(gòu)建對象啦。

import lombok.Builder;

@Builder
public class Coffee extends BaseEntity implements Serializable {
private String name;

private Long price;

......
}

Go 里使用Builder

那在Go?里面要怎么實現(xiàn)Builder模式呢?仿照上面這個模式,我們可以這樣:

假設(shè)我們要在項目里搞個 DB 鏈接池,連接池提供了很多配置化的參數(shù)。

type DBPool struct {
dsn string
maxOpenConn int
maxIdleConn int
...
maxConnLifeTime time.Duration
}

我們給 DB 連接池加一個建造者模式,這樣在設(shè)置每個配置化參數(shù)的時候就可以對參數(shù)進行一步檢查,避免直接 new 連接池對象,再給每個屬性賦值時都加判斷,把每個參數(shù)的校驗內(nèi)聚到參數(shù)自己的建造者步驟里。

type DBPoolBuilder struct {
DBPool
err error
}

func Builder () *DBPoolBuilder {
b := new(DBPoolBuilder)
// 設(shè)置 DBPool 屬性的默認值
b.DBPool.dsn = "127.0.0.1:3306"
b.DBPool.maxConnLifeTime = 1 * time.Second
b.DBPool.maxOpenConn = 30
return b
}

func (b *DBPoolBuilder) DSN(dsn string) *DBPoolBuilder {
if b.err != nil {
return b
}
if dsn == "" {
b.err = fmt.Errorf("invalid dsn, current is %s", dsn)
}

b.DBPool.dsn = dsn
return b
}

func (b *DBPoolBuilder) MaxOpenConn(connNum int) *DBPoolBuilder {
if b.err != nil {
return b
}
if connNum < 1 {
b.err = fmt.Errorf("invalid MaxOpenConn, current is %d", connNum)
}

b.DBPool.maxOpenConn = connNum
return b
}

func (b *DBPoolBuilder) MaxConnLifeTime(lifeTime time.Duration) *DBPoolBuilder {
if b.err != nil {
return b
}
if lifeTime < 1 * time.Second {
b.err = fmt.Errorf("connection max life time can not litte than 1 second, current is %v", lifeTime)
}

b.DBPool.maxConnLifeTime = lifeTime
return b
}

func (b *DBPoolBuilder) Build() (*DBPool, error) {
if b.err != nil {
return nil, b.err
}
if b.DBPool.maxOpenConn < b.DBPool.maxIdleConn {
return nil, fmt.Errorf("max total(%d) cannot < max idle(%d)", b.DBPool.maxOpenConn, b.DBPool.maxIdleConn)
}
return &b.DBPool, nil
}

接下來就可以使用構(gòu)建模式創(chuàng)造DBPool類型的對象了。

package main 

import "xxx/dbpool"

func main() {
dbPool, err := dbpool.Builder().DSN("localhost:3306").MaxOpenConn(50).MaxConnLifeTime(0 * time.Second).Build()
if err != nil {
fmt.Println(err)
}
fmt.Println(dbPool)
}

另外在建造者過程的每個參數(shù)步驟里,我們都借用了之前提到的處理 Go Error 的方式,把在外部調(diào)用時的錯誤判斷,分散到了每個步驟里。

這么一來有從觀感上覺得確實比定義一個參數(shù)巨多的 DBPool 構(gòu)造函數(shù)要好一點。你覺得呢?

Go 里邊還有一個函數(shù)時編程風(fēng)格,利用的是函數(shù)的可變參數(shù) (variadic parameters) ,這種編程模式就是 Option 模式。


名稱欄目:Go開源庫、大項目的公共包,是這么用建造者模式的
網(wǎng)站鏈接:http://m.jiaoqi3.com/article/cogpsid.html