原型模式
wiki:原型模式是建立型模式的一種,其特點在於通過“複製”一個已經存在的例項來返回新的例項,而不是新建例項。被複制的例項就是我們所稱的“原型”,這個原型是可定製的。原型模式多用於建立複雜的或者耗時的例項,因為這種情況下,複製一個已經存在的例項使程式執行更高效;或者建立值相等,只是命名不一樣的同類資料。
這是一個十分簡單的設計模式,可以看做是其他語言中的克隆方法,例如 JAVA
/PHP
中都有相關方法,從一個記憶體中已經存在的物件中,拷貝出一個一模一樣的物件來,針對複雜物件或比較大的物件,要比使用各種設計模式new
出來的物件要快的多,
而且原型模式很少單獨使用,一般與其他物件結合使用。
栗子
-
建立一個結構體
// 示例結構體 type Example struct { Content string } 複製程式碼
-
新增克隆方法
func (e *Example) Clone() *Example { res := *e return &res } 複製程式碼
我們僅僅一行程式碼就完成了值的拷貝,使用
*指標
,直接獲取了一個拷貝的值,然後將這個拷貝的值得指標返回,原理請閱讀下面的擴充套件閱讀。 -
編寫主程式碼
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 ~