Go 常用的設(shè)計模式

常用設(shè)計模式

1. 單例模式:


package singleton

import (
    "sync"
)

type singleton struct {
}

var ins *singleton
var once sync.Once

func GetInsOr() *singleton {
    once.Do(func() {
        ins = &singleton{}
    })
    return ins
}

2. 簡單工廠模式


type Person struct {
  Name string
  Age int
}

func (p Person) Greet() {
  fmt.Printf("Hi! My name is %s", p.Name)
}

func NewPerson(name string, age int) *Person {
  return &Person{
    Name: name,
    Age: age,
  }
}

3. 抽象工廠模式

它返回的是接口而不是結(jié)構(gòu)體砚嘴。


type Person interface {
  Greet()
}

type person struct {
  name string
  age int
}

func (p person) Greet() {
  fmt.Printf("Hi! My name is %s", p.name)
}

// Here, NewPerson returns an interface, and not the person struct itself
func NewPerson(name string, age int) Person {
  return person{
    name: name,
    age: age,
  }
}

4. 工廠方法模式


type Person struct {
  name string
  age int
}

func NewPersonFactory(age int) func(name string) Person {
  return func(name string) Person {
    return Person{
      name: name,
      age: age,
    }
  }
}

5. 策略模式

在項目開發(fā)中穿稳,我們經(jīng)常要根據(jù)不同的場景呼股,采取不同的措施阳啥,也就是不同的策略沸移。比如床牧,假設(shè)我們需要對 a荣回、b 這兩個整數(shù)進行計算,根據(jù)條件的不同戈咳,需要執(zhí)行不同的計算方式心软。為了解耦,需要使用策略模式著蛙,定義一些獨立的類來封裝不同的算法删铃,每一個類封裝一個具體的算法(即策略)。


package strategy

// 策略模式

// 定義一個策略類
type IStrategy interface {
  do(int, int) int
}

// 策略實現(xiàn):加
type add struct{}

func (*add) do(a, b int) int {
  return a + b
}

// 策略實現(xiàn):減
type reduce struct{}

func (*reduce) do(a, b int) int {
  return a - b
}

// 具體策略的執(zhí)行者
type Operator struct {
  strategy IStrategy
}

// 設(shè)置策略
func (operator *Operator) setStrategy(strategy IStrategy) {
  operator.strategy = strategy
}

// 調(diào)用策略中的方法
func (operator *Operator) calculate(a, b int) int {
  return operator.strategy.do(a, b)
}

6. 模板模式

模板模式就是將一個類中能夠公共使用的方法放置在抽象類中實現(xiàn)踏堡,將不能公共使用的方法作為抽象方法猎唁,強制子類去實現(xiàn),這樣就做到了將一個類作為一個模板顷蟆,讓開發(fā)者去填充需要填充的地方诫隅。


package template

import "fmt"

type Cooker interface {
  fire()
  cooke()
  outfire()
}

// 類似于一個抽象類
type CookMenu struct {
}

func (CookMenu) fire() {
  fmt.Println("開火")
}

// 做菜,交給具體的子類實現(xiàn)
func (CookMenu) cooke() {
}

func (CookMenu) outfire() {
  fmt.Println("關(guān)火")
}

// 封裝具體步驟
func doCook(cook Cooker) {
  cook.fire()
  cook.cooke()
  cook.outfire()
}

type XiHongShi struct {
  CookMenu
}

func (*XiHongShi) cooke() {
  fmt.Println("做西紅柿")
}

type ChaoJiDan struct {
  CookMenu
}

func (ChaoJiDan) cooke() {
  fmt.Println("做炒雞蛋")
}

7. 代理模式

可以為另一個對象提供一個替身或者占位符帐偎,以控制對這個對象的訪問逐纬。


package proxy

import "fmt"

type Seller interface {
  sell(name string)
}

// 火車站
type Station struct {
  stock int //庫存
}

func (station *Station) sell(name string) {
  if station.stock > 0 {
    station.stock--
    fmt.Printf("代理點中:%s買了一張票,剩余:%d \n", name, station.stock)
  } else {
    fmt.Println("票已售空")
  }

}

// 火車代理點
type StationProxy struct {
  station *Station // 持有一個火車站對象
}

func (proxy *StationProxy) sell(name string) {
  if proxy.station.stock > 0 {
    proxy.station.stock--
    fmt.Printf("代理點中:%s買了一張票,剩余:%d \n", name, proxy.station.stock)
  } else {
    fmt.Println("票已售空")
  }
}

8. 選項模式


package options

import (
  "time"
)

type Connection struct {
  addr    string
  cache   bool
  timeout time.Duration
}

const (
  defaultTimeout = 10
  defaultCaching = false
)

type options struct {
  timeout time.Duration
  caching bool
}

// Option overrides behavior of Connect.
type Option interface {
  apply(*options)
}

type optionFunc func(*options)

func (f optionFunc) apply(o *options) {
  f(o)
}

func WithTimeout(t time.Duration) Option {
  return optionFunc(func(o *options) {
    o.timeout = t
  })
}

func WithCaching(cache bool) Option {
  return optionFunc(func(o *options) {
    o.caching = cache
  })
}

// Connect creates a connection.
func NewConnect(addr string, opts ...Option) (*Connection, error) {
  options := options{
    timeout: defaultTimeout,
    caching: defaultCaching,
  }

  for _, o := range opts {
    o.apply(&options)
  }

  return &Connection{
    addr:    addr,
    cache:   options.caching,
    timeout: options.timeout,
  }, nil
}

選項模式通常適用于以下場景:

  • 結(jié)構(gòu)體參數(shù)很多,創(chuàng)建結(jié)構(gòu)體時削樊,我們期望創(chuàng)建一個攜帶默認值的結(jié)構(gòu)體變量豁生,并選擇性修改其中一些參數(shù)的值。
  • 結(jié)構(gòu)體參數(shù)經(jīng)常變動漫贞,變動時我們又不想修改創(chuàng)建實例的函數(shù)甸箱。例如:結(jié)構(gòu)體新增一個 retry 參數(shù),但是又不想在 NewConnect 入?yún)⒘斜碇刑砑觬etry int這樣的參數(shù)聲明迅脐。

參考文章

  • Go 語言項目開發(fā)實戰(zhàn)/設(shè)計模式
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末摇肌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仪际,更是在濱河造成了極大的恐慌围小,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡葡幸,警方通過查閱死者的電腦和手機俄烁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烟馅,你說我怎么就攤上這事只锻×跣澹” “怎么了樱溉?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長纬凤。 經(jīng)常有香客問我福贞,道長,這世上最難降的妖魔是什么停士? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任挖帘,我火速辦了婚禮,結(jié)果婚禮上恋技,老公的妹妹穿的比我還像新娘拇舀。我一直安慰自己,他們只是感情好蜻底,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布骄崩。 她就那樣靜靜地躺著,像睡著了一般薄辅。 火紅的嫁衣襯著肌膚如雪刁赖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天长搀,我揣著相機與錄音,去河邊找鬼鸡典。 笑死源请,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的彻况。 我是一名探鬼主播谁尸,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纽甘!你這毒婦竟也來了良蛮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤悍赢,失蹤者是張志新(化名)和其女友劉穎决瞳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體左权,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡皮胡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赏迟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屡贺。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出甩栈,到底是詐尸還是另有隱情泻仙,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布量没,位于F島的核電站玉转,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏允蜈。R本人自食惡果不足惜冤吨,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望饶套。 院中可真熱鬧漩蟆,春花似錦、人聲如沸妓蛮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛤克。三九已至捺癞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間构挤,已是汗流浹背髓介。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留筋现,地道東北人唐础。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像矾飞,于是被迫代替她去往敵國和親一膨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355