GoLang设计模式06 - 对象池模式
这次介绍最后一个创建型模式——对象池模式。顾名思义,对象池模式就是预先初始化创建好多个对象,并将之保存在一个池子里。当需要的时候,客户端就可以从池子里申请一个对象使用,使用完以后再将之放回到池子里。池子里的对象在应用运行期间永远不会被破坏或回收。
适用场景:
- 当需要的对象的创建成本比较高,且该类型的对象在应用运行期间只需要有限的数量
- 对象是不可变的
- 性能原因:预创建的对象可以显著提升应用性能
我们在开发中最熟悉的对象池应该是数据库连接池了。因为网络因素,数据库连接池中的每个对象的创建成本都比较高,且应用在运行期间会需要多个数据库连接对象。另外,每个数据库的连接池中对象的属性都是一样的,且在运行期间这些对象的属性几乎通常都是不可变的。
来看个模拟的数据库连接对象池模型的例子。
iPoolObject.go
1
2
3
4
|
type iPoolObject interface { //This is any id which can be used to compare two different pool objects getID() string } |
connection.go
1
2
3
4
5
6
7
|
type connection struct { id string } func (c *connection) getID() string { return c.id } |
pool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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) } |
输出内容为:
1
2
3
4
|
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!
仅是学习笔记,难免出错,望不吝指点
转 https://www.cnblogs.com/amunote/p/15259628.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)