Go 原型形式讲解和代码示例

原型是一种创建型设计形式, 使你能够复制目标, 甚至是杂乱目标, 而又无需使代码依赖它们所属的类。

所有的原型类都必须有一个通用的接口, 使得即使在目标所属的详细类不知道的情况下也能复制目标。 原型目标能够生成本身的完好副本, 因为相同类的目标能够相互访问对方的私有成员变量。

概念示例

让咱们尝试通过根据操作体系文件体系的示例来理解原型形式。 操作体系的文件体系是递归的: 文件夹中包含文件和文件夹, 其中又包含文件和文件夹, 以此类推。

每个文件和文件夹都可用一个 inode接口来表示。 inode接口中同样也有 clone克隆功能。

file文件和 folder文件夹结构体都实现了 print打印和 clone办法, 因为它们都是 inode类型。 一起, 留意 filefolder中的 clone办法。 这两者的 clone办法都会回来相应文件或文件夹的副本。 一起在克隆过程中, 咱们会在其名称后边添加 “_clone” 字样。

inode.go: 原型接口

package main
type Inode interface {
	printer(string)
	clone() Inode
}

file.go: 详细原型

package main
import "fmt"
type File struct {
	name string
}
func (f *File) print(indentation string) {
	fmt.Println(indentation + f.name)
}
func (f *File) clone() Inode {
	return &File{name: f.name + "_clone"}
}

folder.go: 详细原型

package main
import "fmt"
type Folder struct {
	children []Inode
	name     string
}
func (f *Folder) print(indentation string) {
	fmt.Println(indentation + f.name)
	for _, v := range f.children {
		v.print(indentation + indentation)
	}
}
func (f *Folder) clone() Inode {
	cloneFolder := &Folder{name: f.name + "_clone"}
	var tempChildren []Inode
	for _, v := range f.children {
		copy := v.clone()
		tempChildren = append(tempChildren, copy)
	}
	cloneFolder.children = tempChildren
	return cloneFolder
}

main.go: 客户端代码

package main
import "fmt"
func main() {
	file1 := &File{name: "file1"}
	file2 := &File{name: "file2"}
	file3 := &File{name: "file3"}
	folder1 := &Folder{
		children: []Inode{file1},
		name:     "folder1",
	}
	folder2 := &Folder{
		children: []Inode{folder1, file2, file3},
		name:     "folder2",
	}
	fmt.Println("Print hierarchy for folder2")
	folder2.print(" ")
	cloneFolder := folder2.clone()
	fmt.Println("\nPrinting hierarchy for clone Folder")
	cloneFolder.print("  ")
}

output.txt: 履行结果

Print hierarchy for folder2
 folder2
  folder1
    file1
  file2
  file3
Printing hierarchy for clone Folder
  folder2_clone
    folder1_clone
        file1_clone
    file2_clone
    file3_clone