GoLang设计模式05 - 原型模式
原型模式也是一种创建型模式,它可以帮助我们优雅地创建对象的拷贝。在这种设计模式里面,将克隆某个对象的职责交给了要被克隆的这个对象。被克隆的对象需要提供一个clone()方法。通过这个方法可以返回该对象的拷贝。
原型模式的使用场景:
- 创建新对象的操作比较耗资源(如数据库操作)或代价比较高时。比较起从头创建新对象,克隆对象明显更加可取
- 要被克隆的对象创建起来比较复杂时:比如对象克隆的过程中存在深度拷贝或分层拷贝时;又比如要被克隆的对象存在无法被直接访问到的私有成员时。
原型模式的UML类图:

在日常中我们遇到的包含新建、copy这些操作的场景最多的就是常规的文件系统操作了。所以接下来会以文件系统为例介绍下原型模式。
在文件系统中存在文件(file)和文件夹(folder)两类实体。其中文件夹中又可以包含文件和子文件夹。这里我们用一个inode接口来表示文件和文件夹。为了表示常见的复制操作,在inode接口中还定义了一个clone()函数。
inode.go
type inode interface {
print(string)
clone() inode
}
file 和 folder两个struct实现了inode接口。
file.go
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
import "fmt"
type folder struct {
children []inode
name string
}
func (f *folder) print(indentation string) {
fmt.Println(indentation + f.name)
for _, i := range f.children {
i.print(indentation + indentation)
}
}
func (f *folder) clone() inode {
cloneFolder := &folder{name: f.name + "_clone"}
var tempChildren []inode
for _, i := range f.children {
copy := i.clone()
tempChildren = append(tempChildren, copy)
}
cloneFolder.children = tempChildren
return cloneFolder
}
file和folder两个struct都实现了print()和clone()函数,根据go语言的约定,可以认为它们都继承了inode接口,即可以认为它们是inode类型了。这两者的clone()函数会返回其各自相关的文件或文件夹的备份。为了和原有的文件/文件夹作区分,我们在复制的对象的名称上添加了“_clone”这样的标记。
来看看main函数是怎样的,main.go:
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("\nPrinting hierarchy for Folder2")
folder2.print(" ")
cloneFolder := folder2.clone()
fmt.Println("\nPrinting hierarchy for clone Folder")
cloneFolder.print(" ")
}
运行结果是:
Printing hierarchy for Folder2
Folder2
Folder1
File1
File2
File3 Printing hierarchy for clone Folder
Folder2_clone
Folder1_clone
File1_clone
File2_clone
File3_clone
代码已上传至GitHub, 地址: zhyea / go-patterns / prototype-pattern
END!
GoLang设计模式05 - 原型模式的更多相关文章
- 设计模式_11_原型模式(prototype)深拷贝、浅拷贝
设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...
- C#设计模式(6)——原型模式(Prototype Pattern)
一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...
- 乐在其中设计模式(C#) - 原型模式(Prototype Pattern)
原文:乐在其中设计模式(C#) - 原型模式(Prototype Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 原型模式(Prototype Pattern) 作者:weba ...
- C#设计模式之六原型模式(Prototype)【创建型】
一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...
- C#设计模式之五原型模式(Prototype Pattern)【创建型】
一.引言 在开始今天的文章之前先说明一点,欢迎大家来指正.很多人说原型设计模式会节省机器内存,他们说是拷贝出来的对象,这些对象其实都是原型的复制,不会使用内存.我认为这是不对的,因为拷贝出来的每一个对 ...
- C#设计模式(6)——原型模式(Prototype Pattern)(转)
一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在 ...
- C#设计模式(6)——原型模式(Prototype Pattern) C# 深浅复制 MemberwiseClone
C#设计模式(6)——原型模式(Prototype Pattern) 一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创 ...
- Golang设计模式—简单工厂模式(Simple Factory Pattern)
Golang设计模式--简单工厂模式 背景 假设我们在做一款小型翻译软件,软件可以将德语.英语.日语都翻译成目标中文,并显示在前端. 思路 我们会有三个具体的语言翻译结构体,或许以后还有更多,但现在分 ...
- JAVA 设计模式之原型模式
目录 JAVA 设计模式之原型模式 简介 Java实现 1.浅拷贝 2.深拷贝 优缺点说明 1.优点 2.缺点 JAVA 设计模式之原型模式 简介 原型模式是六种创建型设计模式之一,主要应用于创建相同 ...
随机推荐
- XSS challenges靶机
第一关 <script>alert(123)</script> "><svg onload=alert(123)> 第二关 <script&g ...
- etcd raft 处理流程图系列1-raftexample
最近在看raft相关的代码和实现,发现etcd的raft模块在实现上还是比较灵活的,但缺点就是需要用户实现比较多的功能,如存储和网络等,同时带来的优点就是不会对用户的存储和传输作限制.网上对该模块的描 ...
- 大数据学习(26)—— Spark之RDD
做大数据一定要有一个概念,需要处理的数据量非常大,少则几十T,多则上百P,全部放内存是不可能的,会OOM,必须要用迭代器一条一条处理. RDD叫做弹性分布式数据集,是早期Spark最核心的概念,是一种 ...
- C++//递增运算符重载
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 //重载递增运算符 6 7 //自定义 ...
- iptables 及容器网络分析
本文独立博客阅读地址:https://ryan4yin.space/posts/iptables-and-container-networks/ 本文仅针对 ipv4 网络 iptables 提供了包 ...
- JAVA的一般输入输出 和 快速输入输出 (BufferedReader&BufferedWrite)(转载)
1.JAVA的一般输入输出 和 快速输入输出 (BufferedReader&BufferedWrite) 摘要 本文主要介绍快速输入输出, 文中提到了几个IO类,这里推荐使用Buffered ...
- Share Keyboard, Mouse and Clipboard between Multiple Computers
Synergy version: 1.4.12 Server Download and install synergy-1.4.12-Linux-i686.deb on Mint 14; Run it ...
- 【笔记】逻辑回归中使用多项式(sklearn)
在逻辑回归中使用多项式特征以及在sklearn中使用逻辑回归并添加多项式 在逻辑回归中使用多项式特征 在上面提到的直线划分中,很明显有个问题,当样本并没有很好地遵循直线划分(非线性分布)的时候,其预测 ...
- DVWA靶场之XSS(Reflected)通关
反射型xss Low: <?php header ("X-XSS-Protection: 0"); // Is there any input? if( array_key_ ...
- Java实现WebSocket服务
一.使用Tomcat提供的WebSocket库 Java可以使用Tomcat提供的WebSocket库接口实现WebSocket服务,代码编写也非常的简单.现在的H5联网游戏基本上都是使用WebSo ...