共计 2117 个字符,预计需要花费 6 分钟才能阅读完成。
手撸 golang 创立型设计模式 原型模式
缘起
最近温习设计模式
拜读谭勇德的 << 设计模式就该这样学 >>
本系列笔记拟采纳 golang 练习之
原型模式
原型模式(Prototype Pattern)指原型实例指定创建对象的品种,并且通过复制这些原型创立新的对象,属于创立型设计模式。
_
场景
- 某多用户业务零碎, 提供用户自助注册的性能
- 用户具备 ID, Name, RolList(角色列表)等属性
- 创立用户时, 须要给用户默认调配 ”guest” 角色
- 用户的默认值, 应用 json 文件进行配置
设计
- 定义 UserInfo 类, 示意用户信息
- UserInfo 类实现了 ICloneable 接口, 能够深度克隆本身
- 定义 UserFactory 类, 作为创立新用户的简略工厂
- 初始化 UserFactory 时, 从磁盘加载默认用户的属性配置, 并创立一个 UserInfo 实例, 作为用户信息的原型
- 创立新用户时, 调用原型用户的 Clone()办法, 复制正本并返回
prototype_test.go
单元测试
package patterns
import (
"fmt"
pt "learning/gooop/creational_patterns/prototype"
"testing"
)
func Test_Prototype(t *testing.T) {u1 := pt.DefaultUserFactory.Create()
fmt.Printf("u1 = %v\n", u1)
u2 := pt.DefaultUserFactory.Create()
fmt.Printf("u2 = %v\n", u2)
}
测试输入
$ go test -v prototype_test.go
=== RUN Test_Prototype
u1 = &{0 新用户 [guest]}
u2 = &{0 新用户 [guest]}
--- PASS: Test_Prototype (0.00s)
PASS
ok command-line-arguments 0.002s
ICloneable.go
定义克隆接口
package prototype
type ICloneable interface {Clone() ICloneable
}
UserInfo.go
UserInfo 封装了用户信息, 并实现了 ICloneable 接口, 能够深度克隆本身
package prototype
type UserInfo struct {
ID int
Name string
RoleList []string}
func newEmptyUser() *UserInfo {return &UserInfo{}
}
func (me *UserInfo) Clone() ICloneable {
roles := me.RoleList
it := &UserInfo{me.ID, me.Name, make([]string, len(roles)),
}
for i,s := range roles {it.RoleList[i] = s
}
return it
}
UserFactory.go
UserFactory 实现了创立 UserInfo 的简略工厂.
创立的过程实质是调用了用户原型的 Clone 办法.
用户原型是从 json 配置加载的, 便于按需批改配置.
package prototype
import (
"encoding/json"
"strings"
)
// 用户工厂的全局单例
var DefaultUserFactory IUserFactory = newUserFactory()
type IUserFactory interface {Create() *UserInfo
}
type tUserFactory struct {defaultUserInfo *UserInfo}
// 创立用户工厂实例
func newUserFactory() *tUserFactory {reader := strings.NewReader(loadUserConfig())
decoder := json.NewDecoder(reader)
user := newEmptyUser()
e := decoder.Decode(user)
if e != nil {panic(e)
}
return &tUserFactory{defaultUserInfo: user,}
}
// 加载默认用户的属性配置
func loadUserConfig() string {
return `{
"ID": 0,
"Name" : "新用户",
"RoleList" : ["guest"]
}`
}
func (me *tUserFactory) Create() *UserInfo {return me.defaultUserInfo.Clone().(*UserInfo)
}
原型模式小结
原型模式的长处
(1)某些时候克隆比间接 new 一个对象再逐属性赋值的过程更简洁高效。
(2)能够应用深克隆形式保留对象的状态,可辅助实现撤销操作。
原型模式的毛病
(1)须要配置一个 clone 办法。
(2)clone 办法位于类的外部,当对已有类进行革新的时候,须要批改代码,违反了开闭准则。
(3)当实现深克隆时,须要编写较为简单的代码,尤其当对象之间存在多重嵌套援用时,为了实现深克隆,每一层对象对应的类都必须反对深克隆。因而,深克隆、浅克隆须要使用切当。
(end)
正文完