【设计模式】4、prototype 原型模式

四、prototype 原型模式

https://refactoringguru.cn/design-patterns/prototype

如果希望 复制对象, 可使用 "prototype 模式"

如果 "待复制的对象" 是 interface 而不是 class, 或者如果 class 有 private 变量时. 无法知道 "待复制的对象"的细节, 则需要其实现 "clone()" 方法供外部调用.

4.1 inode

本例希望实现文件系统的复制功能. 数据结构是 inode 接口, file 和 folder 都实现了该接口. 详见 https://refactoringguru.cn/design-patterns/prototype/go/example

当然, 另一条路是: 也可以直接用序列化+反序列化实现复杂对象的 clone()

4.1.1 inode_test

go 复制代码
package _41inode

import "testing"

func TestInode(t *testing.T) {
	d1 := &directory{
		name:     "json",
		children: []inode{&file{name: "a.json"}, &file{name: "b.json"}},
	}
	d2 := &directory{
		name:     "yaml",
		children: []inode{&file{"c.yaml"}, &file{"d.yaml"}},
	}
	f1 := &file{name: "e.txt"}
	f2 := &file{name: "f.sql"}

	directoryHome := directory{
		name:     "/home",
		children: []inode{d1, d2, f1, f2},
	}
	directoryHome.print(printIndent)

	cp := directoryHome.clone()
	cp.print("  ")
}

// code result
=== RUN   TestInode
  /home
    json
      a.json
      b.json
    yaml
      c.yaml
      d.yaml
    e.txt
    f.sql
  /home_clone
    json_clone
      a.json_clone
      b.json_clone
    yaml_clone
      c.yaml_clone
      d.yaml_clone
    e.txt_clone
    f.sql_clone
--- PASS: TestInode (0.00s)
PASS

4.1.2 inode

go 复制代码
package _41inode

// inode 是文件系统的节点
type inode interface {
	// 打印此节点的信息, indent 是缩进符(如\t)
	print(indent string)
	// 复制此节点
	clone() inode
}

const printIndent = "  "

4.1.3 file

go 复制代码
package _41inode

import "fmt"

type file struct {
	// 文件名
	name string
}

func (f *file) print(indent string) {
	str := indent + f.name
	fmt.Println(str)
}

func (f *file) clone() inode {
	return &file{name: f.name + "_clone"}
}

4.1.4 directory

go 复制代码
package _41inode

import (
	"fmt"
)

type directory struct {
	// 目录名
	name string
	// 子节点
	children []inode
}

func (d *directory) print(indent string) {
	fmt.Println(indent + d.name)
	for _, child := range d.children {
		child.print(indent + printIndent) // 在基础 indent 的基础上, 再添加 printIndent
	}
}

func (d *directory) clone() inode {
	children := make([]inode, 0)
	for _, child := range d.children {
		children = append(children, child.clone())
	}
	cp := &directory{
		name:     d.name + "_clone",
		children: children,
	}
	return cp
}
相关推荐
xiaolin03334 分钟前
【设计模式】- 行为型模式1
设计模式·状态模式·责任链模式·策略模式·命令模式·模板方法模式·行为型模式
沐土Arvin1 小时前
深入理解 requestIdleCallback:浏览器空闲时段的性能优化利器
开发语言·前端·javascript·设计模式·html
bao_lanlan2 小时前
兰亭妙微:用系统化思维重构智能座舱 UI 体验
ui·设计模式·信息可视化·人机交互·交互·ux·外观模式
咖啡の猫2 小时前
JavaScript基础-创建对象的三种方式
开发语言·javascript·ecmascript
outstanding木槿2 小时前
react中安装依赖时的问题 【集合】
前端·javascript·react.js·node.js
小吕学编程3 小时前
Jackson使用详解
java·javascript·数据库·json
霸王蟹3 小时前
React中useState中更新是同步的还是异步的?
前端·javascript·笔记·学习·react.js·前端框架
霸王蟹3 小时前
React Hooks 必须在组件最顶层调用的原因解析
前端·javascript·笔记·学习·react.js
总是难免3 小时前
设计模式 - 单例模式 - Tips
java·单例模式·设计模式
听吉米讲故事4 小时前
Slidev集成Chart.js:专业数据可视化演示文稿优化指南
javascript·信息可视化·数据分析