DAY 19:Prototype Pattern,创建物件不再从头开始浪费时间

什麽是 Prototype Pattern?

将物件以拷贝的方式建立

如果某类物件在初始化时,会消耗大量的成本,例如:「对 DB 做 query、读取 json file、读取使用者滑鼠的轨迹」,那在建立完此物件後,又须建立此此类相似的物件时,我们会希望用拷贝(copy)的,以避免初始化的成本。

而拷贝这件事,又有分深拷贝(deep copy)浅拷贝(shallow copy),如果是有 javascript 经验的开发者一定很熟悉这两个词,在 golang 他们主要是:

  • 深拷贝(deep copy):当拷贝时是拷贝数据本身,所以对拷贝的数据修改,不会影响到原本的数据,Int、Float、String、Bool、Struct、Array 都采用这类复制
  • 浅拷贝(shallow copy):当拷贝时是拷贝数据指标,所以对拷贝的数据修改,会影响到原本的数据,Slice、Map 都采用这类复制

使用浅拷贝通常是为了更节省记忆体,但如果复制出来的数据有要完全独立的需求得采用深拷贝,

小节一下 Prototype Pattern 的优缺点:

优点:

  • 不需要初始化的成本

缺点:

  • 需要注意深浅拷贝的差异,不然有可能会修改到原始的数据

问题情境

Sony 已经做出了 PS5 原型机,在这个过程中有经历「建模、分析硬体数据、效能测试」等动作,但现在要量产 PS5,并不需要这些浪费时间的动作,也不需要使用原型的组件来量产。

解决方式

相关的 code 在Github - go-design-patterns

package main

import (
	"fmt"
	"time"
)

type PS5 struct {
	Version string
	CPU     []string
	GPU     map[string]string
}

func (_ PS5) Modeling() {
	time.Sleep(time.Second) // 模拟耗时
}

func (_ PS5) LoadTest() {
	time.Sleep(time.Second) // 模拟耗时
}

func (_ PS5) Analysis() {
	time.Sleep(time.Second) // 模拟耗时
}

func (p *PS5) Clone() *PS5 {
	// 将基本物件拷贝
	ps5 := PS5{}
	ps5 = *p

	// 由於Slice是浅拷贝,所以必须透过copy方法来把深层元素拷贝
	cpu := make([]string, len(p.CPU))
	copy(cpu, p.CPU)
	ps5.CPU = cpu

	// 由於Map是浅拷贝,所以需把元素一个一个拿出来拷贝
	gpu := make(map[string]string)
	for k, v := range p.GPU {
		gpu[k] = v
	}
	ps5.GPU = gpu

	return &ps5
}

func CreatePrototypePS5() *PS5 {
	prototypePS5 := PS5{
		Version: "Prototype",
		CPU:     []string{"原型CPU"},
		GPU:     make(map[string]string),
	}
	prototypePS5.GPU["GPU"] = "原型GPU"
	prototypePS5.Modeling()
	prototypePS5.LoadTest()
	prototypePS5.Analysis()
	return &prototypePS5
}

func main() {
	prototypePS5 := CreatePrototypePS5()
	ps5 := prototypePS5.Clone()
	ps5.Version = "Version-1"
	ps5.CPU[0] = "量产CPU"
	ps5.GPU["GPU"] = "量产GPU2"
	fmt.Println(prototypePS5)
	fmt.Println(ps5)
}

范例中PS5{}.CPUPS5{}.GPU分别是 Slice 与 Map,由於都是浅拷贝的数据,所以需要手动以copy()与 for 回圈来将物件元素一个一个复制,而PS5{}.Version就不需要手动复制,因为是深拷贝的数据形态


<<:  【领域展开 17 式】 如何使用 Envato Market 更新 WordPress 布景主题与套件到最新版本

>>:  Day 31:「不够吃了...哪里还有红萝卜?」- Tailwind 和 Vue 的资源分享

Day03_神说要有光~资安三要素V.S.资产盘点 XD"(我会不会因为乱下标题被打)

今天在思考。。。我要乖乖照着上课的笔记打吗?想想,我还是随我自已的意思讲好了,啊呜~ 来人~请播放『...

Day 20 - Android Studio的EditText的基本使用

Day 20 - Android Studio的EditText的基本使用 上一篇我们讲到了网路So...

Annotation 的设计与想法

Annotation 要怎麽定义会影响使用这个 library 的使用者体验,annotation ...

Progressive Web App 透过系统分享内容: Web Share API & Web Share Target (17)

什麽是 Web Share API Web App 透过 Web Share API 就能够使用系统...

计画赶不上变化的第一篇

这一届的 IT 铁人赛,本来排开了很多事情,想要来挑战4个题目,还为了影片组买了一些器材。 但果然,...