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 设计模式之原型模式 简介 原型模式是六种创建型设计模式之一,主要应用于创建相同 ...
随机推荐
- SpringBoot 默认json解析器详解和字段序列化自定义
前言 在我们开发项目API接口的时候,一些没有数据的字段会默认返回NULL,数字类型也会是NULL,这个时候前端希望字符串能够统一返回空字符,数字默认返回0,那我们就需要自定义json序列化处理 Sp ...
- ;~ 小部分AutoHotkey源代码片段测试模板2019年10月9日.ahk
;~ 小部分AutoHotkey源代码片段测试模板2019年10月9日.ahk ;~ 此脚本用于测试执行一行或多行AHK脚本源代码的效果;~ 此脚本最后修改于2019年9月22日20时03分;~ 把此 ...
- 解决移动端在IOS中input输入框光标过长
在输入框样式中加入: line-height:20px;
- javascript的入门学习
目录 JavaScript的学习 什么是javascript,如下简称JS 正式使用js js的两种引入方式 head标签与body标签的区别 js定义变量 可以分为如下四种类型: 有3种特殊的数据类 ...
- 洛谷P3052题解
题面 看起来非常简单,但是细节多的一批的状压DP入门题. 我设 \(f_i\) 为 \(i\) 状态时最小分组数, \(g_i\) 为 \(i\) 状态时最后一组剩余空间. 对于每一个 \(i\) , ...
- XCTF-simple unpack
题目提示这是一个加壳的二进制文件,拖到exeinfope,是UPX壳. 这里我们用linux命令upx -d脱壳. 脱完壳之后拉入ida64中分析.找到main函数,可以看到这一句可以是输出flag的 ...
- Deepin Pwn环境的配置
要学习Pwn Pwn环境那是必不可少滴! 我是新手,我也弄了好久,这里把经验分享给大家!这里感谢I春秋的"知世"老师的脚本!虽然写的不是很完美.还得我自己动手修改!PS:http ...
- 《MySQL实战45讲》(8-15)笔记
MySQL实战45讲 目录 MySQL实战45讲 第八节: 事务到底是隔离的还是不隔离的? 在MySQL里,有两个"视图"的概念: "快照"在MVCC里是怎么工 ...
- 玩转Java8日期工具类-基础
内容基于的是 Java8官方文档,以及Java时间类总结 的总结.BTW:其实具体方法的使用直接在IDEA中看源码更方便直接. 1.老一辈:Java.util.Date Java.sql.Date J ...
- MySQL-14-备份恢复
备份类型 1 热备 在业务正常时,对数据库进行备份数据,并且能够一致性恢复(只能是innodb) 对业务影响非常小 2 温备 锁表备份,只能查询不能修改(myisam) 影响到写入操作 3 冷备 关闭 ...