设计模式--原型模式(Go语言描述)

设计模式–原型模式(Go语言描述)

原型模式

UML


class.png

原型模式通常含有一下角色:

  1. Client(客户端): 在实现中调用原型类,通过使用Clone方法生产多个对象
  2. Prototype(公共接口): 原型接口或抽象类,声明了原型类所需实现的Clone方法
  3. ConcretePrototype(原型类): 实现了接口中的Clone方法,生产一个以自己为基础的克隆对象
示例

浅拷贝原型模式:

package main

import (
    "fmt"
)

type Prototype interface {
    Clone() Prototype
}

type Persion struct {
    Age int
    Hobbies map[int]string
}

func NewPersion(age int, hobbies map[int]string) *Persion{
    return &Persion{
        Age: age,
        Hobbies: hobbies,
    }
}

// 浅拷贝
func (p *Persion)Clone() *Persion{
    return p
}

func main(){
    hobbies := map[int]string{
        1: "football",
        2: "basketball",
    }
    li := NewPersion(20, hobbies)
    // li's information:&{age:20 hobbies:map[2:basketball 1:football]}
    fmt.Printf("li's information:%+v\n",li)
    wang := li.Clone()
    // wang's information:&{Age:20 Hobbies:map[1:football 2:basketball]}
    fmt.Printf("wang's information:%+v\n", wang)
    wang.Hobbies[1] = "ball"
    // li's information:&{Age:20 Hobbies:map[1:ball 2:basketball]}
    fmt.Printf("li's information:%+v\n",li)
    // wang's information:&{Age:20 Hobbies:map[1:ball 2:basketball]}
    fmt.Printf("wang's information:%+v\n", wang)
}

深拷贝原型模式:

package main

import (
    "fmt"
)

type Prototype interface {
    Clone() Prototype
}

type Persion struct {
    Age int
    Hobbies map[int]string
}

func NewPersion(age int, hobbies map[int]string) *Persion{
    return &Persion{
        Age: age,
        Hobbies: hobbies,
    }
}

// 深拷贝
func (p *Persion)Clone() *Persion{
    hobbies := make(map[int]string)
    for key, hobby := range p.Hobbies {
        hobbies[key] = hobby
    }
    return &Persion{
        Age: p.Age,
        Hobbies: hobbies,
    }
}

func main(){
    hobbies := map[int]string{
        1: "football",
        2: "basketball",
    }
    li := NewPersion(20, hobbies)
    // li's information:&{age:20 hobbies:map[2:basketball 1:football]}
    fmt.Printf("li's information:%+v\n",li)
    wang := li.Clone()
    // wang's information:&{Age:20 Hobbies:map[1:football 2:basketball]}
    fmt.Printf("wang's information:%+v\n", wang)
    wang.Hobbies[1] = "ball"
    // li's information:&{Age:20 Hobbies:map[1:football 2:basketball]}
    fmt.Printf("li's information:%+v\n",li)
    // wang's information:&{Age:20 Hobbies:map[1:ball 2:basketball]}
    fmt.Printf("wang's information:%+v\n", wang)
}

原型模式分为浅拷贝深拷贝,如示例中所写,当实现为浅拷贝时,更改拷贝项中的指针引用对象,源自同一个原型的全部的克隆对象都会受到影响,而通过重新申请内存空间实现深拷贝模式,在修改引用对象的指针引用项时,不会影响其他的克隆对象。

小结

原型模式主要应用于实例化对象较为复杂繁琐、成本较大的场景,通过克隆复制已有的原型对象,简化创建过程,提高效率。
在使用原型对象时,需要根据对象成员的实际情况选择深拷贝或浅拷贝。

本文使用CC BY-NA-SA 4.0协议许可
本文链接:http://404-notfound.com/prototype/