golang設計模式之原型模式

silsuer在掘金發表於2019-02-28

原型模式

wiki:原型模式是建立型模式的一種,其特點在於通過“複製”一個已經存在的例項來返回新的例項,而不是新建例項。被複制的例項就是我們所稱的“原型”,這個原型是可定製的。原型模式多用於建立複雜的或者耗時的例項,因為這種情況下,複製一個已經存在的例項使程式執行更高效;或者建立值相等,只是命名不一樣的同類資料。

這是一個十分簡單的設計模式,可以看做是其他語言中的克隆方法,例如 JAVA/PHP 中都有相關方法,從一個記憶體中已經存在的物件中,拷貝出一個一模一樣的物件來,針對複雜物件或比較大的物件,要比使用各種設計模式new出來的物件要快的多,

而且原型模式很少單獨使用,一般與其他物件結合使用。

栗子

  1. 建立一個結構體

      // 示例結構體
      type Example struct {
      	Content string
      }
    複製程式碼
  2. 新增克隆方法

      func (e *Example) Clone() *Example {
      	res := *e
      	return &res
      }
    複製程式碼

    我們僅僅一行程式碼就完成了值的拷貝,使用 *指標,直接獲取了一個拷貝的值,然後將這個拷貝的值得指標返回,原理請閱讀下面的擴充套件閱讀。

  3. 編寫主程式碼

   func main() {
   	r1 := new(Example)
   	r1.Content = "this is example 1"
   	r2 := r1.Clone()
   	r2.Content = "this is example 2"
   
   	fmt.Println(r1)
   	fmt.Println(r2)
   
   }
複製程式碼

擴充套件閱讀: 深拷貝與淺拷貝

go 語言中的傳遞都是值傳遞,傳遞一個物件,就會把物件拷貝一份傳入函式中,傳遞一個指標,就會把指標拷貝一份傳入進去。

賦值的時候也是這樣,res:=*e 就會把傳遞的 Example 物件拷貝一份,如果是 res:=e 的話,那麼拷貝的就是物件的指標了.

而深拷貝和淺拷貝也可以這樣理解,深拷貝就是拷貝整個物件,淺拷貝就是拷貝物件指標。

對於深度拷貝,go和其他語言還經常使用序列化後反序列化的形式進行拷貝:

 func deepCopy(dst, src interface{}) error {
     var buf bytes.Buffer
     if err := gob.NewEncoder(&buf).Encode(src); err != nil {
         return err
     }
     return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
  }
複製程式碼

實際上gob包序列化的時候也是用到了 reflect包來實現拷貝的

注意: golang完全是按值傳遞,所以如果深度拷貝的物件中包含有指標的話,那麼深度拷貝後,這些指標也會相同,會導致部分資料共享,要注意這一點.

至此,所有建立型的設計模式就已經全部寫完了,可以去下面的倉庫中找到其他的設計模式喔….

上述程式碼均放在 golang-design-patterns 這個倉庫中

打個廣告,推薦一下自己寫的 go web框架 bingo,求star,求PR ~

相關文章