GoLang设计模式06 - 对象池模式
这次介绍最后一个创建型模式——对象池模式。顾名思义,对象池模式就是预先初始化创建好多个对象,并将之保存在一个池子里。当需要的时候,客户端就可以从池子里申请一个对象使用,使用完以后再将之放回到池子里。池子里的对象在应用运行期间永远不会被破坏或回收。
适用场景:
- 当需要的对象的创建成本比较高,且该类型的对象在应用运行期间只需要有限的数量
- 对象是不可变的
- 性能原因:预创建的对象可以显著提升应用性能
我们在开发中最熟悉的对象池应该是数据库连接池了。因为网络因素,数据库连接池中的每个对象的创建成本都比较高,且应用在运行期间会需要多个数据库连接对象。另外,每个数据库的连接池中对象的属性都是一样的,且在运行期间这些对象的属性几乎通常都是不可变的。
来看个模拟的数据库连接对象池模型的例子。
iPoolObject.go
type iPoolObject interface {
//This is any id which can be used to compare two different pool objects
getID() string
}
connection.go
type connection struct {
id string
} func (c *connection) getID() string {
return c.id
}
pool.go
import (
"fmt"
"sync"
) type pool struct {
idle []iPoolObject
active []iPoolObject
capacity int
muLock *sync.Mutex
} //initPool Initialize the pool
func initPool(poolObjects []iPoolObject) (*pool, error) {
if len(poolObjects) == 0 {
return nil, fmt.Errorf("cannot craete a pool of 0 length")
}
active := make([]iPoolObject, 0)
pool := &pool{
idle: poolObjects,
active: active,
capacity: len(poolObjects),
muLock: new(sync.Mutex),
}
return pool, nil
} func (p *pool) loan() (iPoolObject, error) {
p.muLock.Lock()
defer p.muLock.Unlock()
if len(p.idle) == 0 {
return nil, fmt.Errorf("no pool object free. Please request after sometime")
}
obj := p.idle[0]
p.idle = p.idle[1:]
p.active = append(p.active, obj)
fmt.Printf("Loan Pool Object with ID: %s\n", obj.getID())
return obj, nil
} func (p *pool) receive(target iPoolObject) error {
p.muLock.Lock()
defer p.muLock.Unlock()
err := p.remove(target)
if err != nil {
return err
}
p.idle = append(p.idle, target)
fmt.Printf("Return Pool Object with ID: %s\n", target.getID())
return nil
} func (p *pool) remove(target iPoolObject) error {
currentActiveLength := len(p.active)
for i, obj := range p.active {
if obj.getID() == target.getID() {
p.active[currentActiveLength-1], p.active[i] = p.active[i], p.active[currentActiveLength-1]
p.active = p.active[:currentActiveLength-1]
return nil
}
}
return fmt.Errorf("targe pool object doesn't belong to the pool")
}
main.go
import (
"log"
"strconv"
) func main() {
connections := make([]iPoolObject, 0)
for i := 0; i < 3; i++ {
c := &connection{id: strconv.Itoa(i)}
connections = append(connections, c)
}
pool, err := initPool(connections)
if err != nil {
log.Fatalf("Init Pool Error: %s", err)
}
conn1, err := pool.loan()
if err != nil {
log.Fatalf("Pool Loan Error: %s", err)
}
conn2, err := pool.loan()
if err != nil {
log.Fatalf("Pool Loan Error: %s", err)
}
_ = pool.receive(conn1)
_ = pool.receive(conn2)
}
输出内容为:
Loan Pool Object with ID: 0
Loan Pool Object with ID: 1
Return Pool Object with ID: 0
Return Pool Object with ID: 1
代码已上传至GitHub:zhyea / go-patterns / object-pool-pattern
END!
GoLang设计模式06 - 对象池模式的更多相关文章
- 游戏开发设计模式之对象池模式(unity3d 示例实现)
前篇:游戏开发设计模式之命令模式(unity3d 示例实现) 博主才学尚浅,难免会有错误,尤其是设计模式这种极富禅意且需要大量经验的东西,如果哪里书写错误或有遗漏,还请各位前辈指正. 原理:从一个固定 ...
- java设计模式之实现对象池模式示例分享
http://www.jb51.net/article/46941.htm 对象池模式经常用在频繁创建.销毁对象,且对象创建.销毁开销很大的场景,比如数据库连接池.线程池.任务队列池等.本代码简单,没 ...
- 对象池模式(Object Pool Pattern)
本文节选自<设计模式就该这样学> 1 对象池模式的定义 对象池模式(Object Pool Pattern),是创建型设计模式的一种,将对象预先创建并初始化后放入对象池中,对象提供者就能利 ...
- C++设计模式 之 “对象性能” 模式:Singleton、Flyweight
“对象性能”模式 面向对象很好地解决了“抽象”的问题,但是必不可免地要付出一定的代价.对于通常情况来讲,面向对象的成本大都可以忽略不计.但是某些情况,面向对象所带来的成本必须谨慎处理. 典型模式 # ...
- C++设计模式 之 “对象创建”模式:Factory Method、Abstract Factory、Prototype、Builder
part 0 “对象创建”模式 通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式 Fact ...
- GoLang设计模式3 - 抽象工厂模式
之前我们介绍了工厂设计模式,现在我们再看一下抽象工厂设计模式.抽象工程模式顾名思义就是对工厂模式的一层抽象,也是创建型模式的一种,通常用来创建一组存在相关性的对象. UML类图大致如下: 类图比较复杂 ...
- GoLang设计模式07 - 责任链模式
责任链模式是一种行为型设计模式.在这种模式中,会为请求创建一条由多个Handler组成的链路.每一个进入的请求,都会经过这条链路.这条链路上的Handler可以选择如下操作: 处理请求或跳过处理 决定 ...
- php设计模式 数据对象映射模式
数据对象映射模式,是将对象和数据存储映射起来,对一个对象的操作会映射为对数据存储的操作. 在代码中实现数据对象映射模式,实现一个ORM类,将复杂的sql语句映射成对象属性的操作.对象关系映射(Obje ...
- 游戏设计模式——Unity对象池
对象池这个名字听起来很玄乎,其实就是将一系列需要反复创建和销毁的对象存储在一个看不到的地方,下次用同样的东西时往这里取,类似于一个存放备用物质的仓库. 它的好处就是避免了反复实例化个体的运算,能减少大 ...
随机推荐
- C中的内置函数
1 //#include <stdio.h> 2 //#include <ctype.h> 3 //#include <math.h> 4 //#include & ...
- 能够进行多段文本匹配的NFA改良算法
下面的代码基于NFA算法实现了在多段字符串中匹配正则表达式,对比NFA算法可以看到它将pc由局部变量提升为类成员,以保存中间匹配状态,另外在匹配成功后将pc恢复到null状态.实际使用中,此类还应该增 ...
- 使用TestNG,Apahcje POI和Excel文件进测试行数据驱动测试
import com.cxy_fanwe.common.test_fanwe_qiantai;import org.apache.http.Header;import org.apache.http. ...
- 一个极其朴素的目录扫描Python脚本
如果目录扫描工具被某些种类的waf拦截了,可以尝试(只是尝试,不是绝对能过)用脚本发出请求,具体功能看需求而定 原理...没啥原理,也没啥技术含量,相信大家都能看得懂的,nobody knows be ...
- 【死磕 Java 基础】— 我同事一个 select 分页语句查出来了 3000W 条数据
大家好,我是大明哥,一个专注于[死磕 Java]系列创作的男人 个人网站:https://www.cmsblogs.com/.专注于 Java 优质系列文章分享,提供一站式 Java 学习资料 某天我 ...
- SQL 练习30
查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况) SELECT Student.*,CId,score from Student LEFT JOIN SC ON Student.SId = ...
- OpenCV 之 自定义滤波
图像处理中,"空间域" 指的是图像平面,因此,空间滤波 可定义为:在图像平面内对像素灰度值进行的滤波 1 空间滤波 1.1 滤波过程 如图,Filter 是一个 3x3 滤波核 ...
- docker部署minio
快速部署 docker run -p 9000:9000 --name myminio \ -e "MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" \ ...
- Centos7上yum安装mongodb(安装epel中的版本可能会比较老)
yum install epel-release 搜索mongodb-server 安装mongodb yum install mongodb-server.x86_64 配置mongodb vim ...
- 【小技巧】排名前 16 的 Java 工具类!
转自java技术栈: https://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247485460&idx=1&sn=cef ...