大家好,我是追麾(hui)。
这是Go的设计模式第三篇,这篇主要分享原型模式,构造器模式。下面我们来看具体模式。
业界原型模式定义:通过复制自己达到构造目标对象新实例的对象。
原型模式优缺点
由于原型模式会存在浅复制和深度复制的问题,所以我们看下关于深复制和浅复制相关的知识。
浅拷贝:拷贝对象指针,其实是引用地址都一样,所以属于牵一发动全身。
深拷贝:拷贝整个对象,源对象和拷贝对象没有任何关联,也不会受到任何影响。
原型模式的应用场景
Go原型模式实现方式
package main
import (
"bytes"
"encoding/gob"
"fmt"
)
func main() {
t1 := ProtoType{
String: "2",
Int: 3,
Slice: []int{2, 32},
Map: map[string]string{"1": "4"},
}
t2, err := t1.Clone()
if err != nil {
fmt.Println("clone 失败")
return
}
if t2.Slice != nil {
t2.Slice[0] = 8
}
if t2.Map != nil {
t2.Map["1"] = "5"
}
fmt.Println(t1, "\n", t2)
}
// 这个是原型对象
type ProtoType struct {
String string
Int int
Slice []int
Map map[string]string
}
// 给对象添加Clone方法
func (p *ProtoType) Clone() (*ProtoType, error) {
// 下面代码是浅拷贝,实际要考虑引用类型的拷贝, 没有使用到引用类型的对象可以使用下面的方式
// tObj := *p
var tObj ProtoType
// 一般实现深拷贝通过gob库实现
buf := bytes.Buffer{}
if err := gob.NewEncoder(&buf).Encode(p); err != nil {
fmt.Println(err)
return nil, err
}
gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(tObj)
return &tObj, nil
}
业界构造器模式定义:指为构造一个复杂的产品对象进行产品组成元素构建和产品组装的对象。简单点说将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。构造器模式也称建造者模式。
构造器模式优缺点
构造器模式的应用场景
构造器模式由产品、抽象构造者、具体构造者、指挥者等 4 个要素构成,现在我们来分析其基本结构和实现方法。
构造器模式的结构:
构造器模式实现方式
产品角色:武器,抽象构造者是士兵,实体构造器也是士兵,指挥者是主人,在游戏中我们经常会指挥士兵去铸造武器,然后去和其他人对抗。下面我们来写一下这个示例。
package main
import "fmt"
func main() {
// 一个游戏者
player := GamePlayers{}
// 一个士兵
oneSoldier := OneSoldier{}
// 游戏者指挥士兵
player.SetSoldiers(oneSoldier)
// 游戏者指挥士兵干货
player.ToDealArms()
}
// 武器对象
type Arms struct {
}
// 士兵抽象构造类
type Soldier interface {
// 打铁
ForgeIron() error
// 冶炼
Smelting() error
// 组装
PackageArms() *Arms
}
// 实体士兵构造者
type OneSoldier struct {
}
// 打铁
func (o *OneSoldier) ForgeIron() error {
fmt.Println("进行打铁操作~")
return nil
}
// 冶炼
func (o *OneSoldier) Smelting() error {
fmt.Println("进行冶炼操作~")
return nil
}
// 组装
func (o *OneSoldier) PackageArms() *Arms {
fmt.Println("进行组装生成武器~")
arms := Arms{}
return &arms
}
// 游戏玩家 - 指挥一士兵
type GamePlayers struct {
SoldierList OneSoldier
}
func (g *GamePlayers) SetSoldiers(s OneSoldier) {
g.SoldierList = s
}
func (g *GamePlayers) GetArms() *Arms {
return g.SoldierList.PackageArms()
}
// 指挥士兵打铁,冶炼,组装,铸造成兵器
func (g *GamePlayers) ToDealArms() *Arms {
g.SoldierList.ForgeIron()
g.SoldierList.Smelting()
return g.SoldierList.PackageArms()
}
GO设计模式和面试八股文
【建议收藏】如何用Go写出优美的代码-Go的设计模式【单例模式,工厂方法模式】篇一
【建议收藏】如何用Go写出优美的代码-Go的设计模式【简单工厂模式,抽象工厂模式】篇二
如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发,您的支持是我坚持写作最大的动力。