golang設計模式


1.單例模式

package singleton

import "sync"

//Singleton 是單例模式類
type Singleton struct{}

var singleton *Singleton
var once sync.Once

//GetInstance 用於獲取單例模式對象
func GetInstance() *Singleton {
    once.Do(func() {
        singleton = &Singleton{}
    })

    return singleton
}

2.裝飾模式

  • 裝飾模式用於動態地給一個對象增加一些額外的職責,就增加對象功 能來說,裝飾模式比生成子類實現更為靈活。它是一種對象結構型模 式。
  • 裝飾模式包含四個角色:抽象構件定義了對象的接口,可以給這些對 象動態增加職責(方法);具體構件定義了具體的構件對象,實現了 在抽象構件中聲明的方法,裝飾器可以給它增加額外的職責(方法); 抽象裝飾類是抽象構件類的子類,用於給具體構件增加職責,但是具 體職責在其子類中實現;具體裝飾類是抽象裝飾類的子類,負責向構 件添加新的職責。
  • 使用裝飾模式來實現擴展比繼承更加靈活,它以對客戶透明的方式動 態地給一個對象附加更多的責任。裝飾模式可以在不需要創造更多子 類的情況下,將對象的功能加以擴展。
  • 裝飾模式的主要優點在於可以提供比繼承更多的靈活性,可以通過一種動態的 方式來擴展一個對象的功能,並通過使用不同的具體裝飾類以及這些裝飾類的 排列組合,可以創造出很多不同行為的組合,而且具體構件類與具體裝飾類可 以獨立變化,用戶可以根據需要增加新的具體構件類和具體裝飾類;其主要缺 點在於使用裝飾模式進行系統設計時將產生很多小對象,而且裝飾模式比繼承 更加易於出錯,排錯也很困難,對於多次裝飾的對象,調試時尋找錯誤可能需 要逐級排查,較為煩瑣。
  • 裝飾模式適用情況包括:在不影響其他對象的情況下,以動態、透明的方式給 單個對象添加職責;需要動態地給一個對象增加功能,這些功能也可以動態地 被撤銷;當不能采用繼承的方式對系統進行擴充或者采用繼承不利於系統擴展 和維護時。

3.代理模式

package proxy

type Subject interface {
    Do() string
}

type RealSubject struct{}

func (RealSubject) Do() string {
    return "real"
}

type Proxy struct {
    real RealSubject
}

func (p Proxy) Do() string {
    var res string

    // 在調用真實對象之前的工作,檢查緩存,判斷權限,實例化真實對象等。。
    res += "pre:"

    // 調用真實對象
    res += p.real.Do()

    // 調用之后的操作,如緩存結果,對結果進行處理等。。
    res += ":after"

    return res
}

4.觀察者模式

package observer

import "fmt"

type Subject struct {
    observers []Observer
    context   string
}

func NewSubject() *Subject {
    return &Subject{
        observers: make([]Observer, 0),
    }
}

func (s *Subject) Attach(o Observer) {
    s.observers = append(s.observers, o)
}

func (s *Subject) notify() {
    for _, o := range s.observers {
        o.Update(s)
    }
}

func (s *Subject) UpdateContext(context string) {
    s.context = context
    s.notify()
}

type Observer interface {
    Update(*Subject)
}

type Reader struct {
    name string
}

func NewReader(name string) *Reader {
    return &Reader{
        name: name,
    }
}

func (r *Reader) Update(s *Subject) {
    fmt.Printf("%s receive %s\n", r.name, s.context)
}

5.工廠模式

Simple Factory Pattern(簡單工廠模式)

在簡單工廠模式中,可以根據參數的不同返回不同類的實例。
eg:

// AB interface
type AB interface {
    Say(name string) string
}

// A .
type A struct{}

// Say .
func (*A) Say(name string) string {
    return fmt.Sprintf("我是A實例, %s", name)
}

// B .
type B struct{}

// Say .
func (*B) Say(name string) string {
    return fmt.Sprintf("我是B實例, %s", name)
}

// NewAB 根據參數不同返回不同實例
func NewAB(t int) AB {
    if t == 1 {
        return &A{}
    }
    return &B{}
}

Factory Method Pattern 工廠模式方法

在工廠方法模式中,核心的工廠類不再負責所有產品的創建,而是將具體創建工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實現的接口,而不負責產品類被實例化這種細節
eg:

// Operator 是被封裝的實際類接口
type Operator interface {
    SetA(int)
    SetB(int)
    Result() int
}

// OperatorFactory 是工廠接口
type OperatorFactory interface {
    Create() Operator
}

// OperatorBase 是Operator 接口實現的基類,封裝公用方法
type OperatorBase struct {
    a, b int
}

// SetA 設置 A
func (o *OperatorBase) SetA(a int) {
    o.a = a
}

// SetB 設置 B
func (o *OperatorBase) SetB(b int) {
    o.b = b
}

//MinusOperator Operator 的實際減法實現
type MinusOperator struct {
    *OperatorBase
}

// PlusOperator Operator 的實際加法實現
type PlusOperator struct {
    *OperatorBase
}

// PlusOperatorFactory 是 PlusOperator 的工廠類
type PlusOperatorFactory struct{}

func (PlusOperatorFactory) Create() Operator {
    return &PlusOperator{
        OperatorBase: &OperatorBase{},
    }
}

// MinusOperatorFactory 是 MinusOperator 的工廠類
type MinusOperatorFactory struct{}

func (MinusOperatorFactory) Create() Operator {
    return &MinusOperator{
        OperatorBase: &OperatorBase{},
    }
}

//Result 獲取結果
func (o PlusOperator) Result() int {
    return o.a + o.b
}

//Result 獲取結果
func (o MinusOperator) Result() int {
    return o.a - o.b
}

Abstract Factory 抽象工廠模式

當系統所提供的工廠所需生產的具體產品並不是一個簡單的對象,而是多個位於不同產品等級結構中屬於不同類型的具體產品時需要使用抽象工廠模式。

抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態。抽象工廠模式與工廠方法模式最大的區別在於,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式則需要面對多個產品等級結構。

// 工廠接口和產品接口
 type FactoryInterface interface {
       CreatePigMeatBuns() ProductInterface // 創建豬肉餡產品
       Create3SBuns() ProductInterface      // 創建三鮮餡產品
   }
   
   type ProductInterface interface {
       Intro()
   }
   // 實現4種產品
   type GDPigMeatBuns struct {
  }

  func (p GDPigMeatBuns) Intro() {
      fmt.Println("廣東豬肉餡包子")
  }
  .....
  // 實現工廠
  // 齊市包子鋪 
  type QSFactory struct {
  }

  func (qs QSFactory) CreatePigMeatBuns() ProductInterface {
      return QSPigMeatBuns{}
  }

  func (qs QSFactory) Create3SBuns() ProductInterface {
      return QS3SBuns{}
  }
  // 廣東包子鋪
  type GDFactory struct {
  }

  func (gd GDFactory) CreatePigMeatBuns() ProductInterface {
      return GDPigMeatBuns{}
  }

  func (gd GDFactory) Create3SBuns() ProductInterface {
      return GD3SBuns{}
  }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM