自学内容网 自学内容网

【设计模式】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

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

package _41inode

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

const printIndent = "  "

4.1.3 file

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

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
}


原文地址:https://blog.csdn.net/jiaoyangwm/article/details/137757566

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!