iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0
自我挑戰組

掘地土撥鼠的設計歷險記系列 第 8

Object Pool - 物件池模式

  • 分享至 

  • xImage
  •  

Introduction

在這個模型中,物件們預先被初始化並儲存在Pool中,使用端可以跟Pool請求一個特定物件並使用。物件池模式可以減少建立物件造成的效能浪費。通常來說,物件在被建立時就會被放進物件池中,往後的調用的物件都是池中的物件,可以加快速度。

物件池模式中的角色有

  • 物件池 ( Pool ): 用於保存物件和處理請求事件
  • 使用端 ( Client )
  • 可重用物件池 ( Reusable ): 用於判斷物件池是否可重用

使用場景

  • 如果需要提高記憶體管理效率,即可使用此模式
  • 需要創大量的物件時,可以使用此模式。舉個例子資料庫連線時,由於物件創建時會涉及到網路連線,建立的資源消耗會稍高,因此較適合使用物件池模式。
  • 當物件是個不可變物件時,也可使用物件池模式。再以資料庫為例,該物件建立之後幾乎不需要更改其屬性,因此也- - 適合使用此模式。
  • 提升性能時,也可使用此模式。
  • 需要再短時間內創建及銷毀大量物件時,也可使用此模式。

雛形演練

UML

https://ithelp.ithome.com.tw/upload/images/20230905/20115082UUtc43fgCi.jpg

Pool

package pools

import (
	"sync"
)

type Pool struct {
	sync.Mutex
	Inuse     []interface{}
	Available []interface{}
	New       func() interface{}
}

func NewPool(new func() interface{}) *Pool {
	return &Pool{New: new}
}

func (p *Pool) Acquire() interface{} {
	p.Lock()
	var object interface{}

	if len(p.Inuse) != 0 {
		object = p.Available[0]
		// TODO: remove first element of Available
		p.Available = append(p.Available[:0], p.Available[1:]...)
		// TODO: add one in Inuse
		p.Inuse = append(p.Inuse, object)
	} else {
		object = p.New()
		p.Inuse = append(p.Inuse, object)
	}
	p.Unlock()
	return object
}

Reusable

package pools

func (p *Pool) Release(object interface{}) {
	p.Lock()
	p.Available = append(p.Available, object)
	for i, v := range p.Inuse {
		if v == object {
			// TODO: remove object from Inuse and add it to last element of Inuse
			p.Inuse = append(p.Inuse[:i], p.Inuse[i+1:]...)
			break
		}
	}
	p.Unlock()
}

main

package main

import (
	"fmt"
	pools "object-pool/Pools"
)

func main() {
	num := func() interface{} {
		return 10.0
	}

	pool := pools.NewPool(num)
	object := pool.Acquire()

	fmt.Println(pool.Inuse, "... Pool Inuse")
	fmt.Println(pool.Available, "... Pool Available")

	pool.Release(object)
	fmt.Println(pool.Inuse, "... Pool Inuse")
	fmt.Println(pool.Available, "... Pool Available")
}

輸出結果優缺點分析

優點

  • 性能優化
  • 資源控制:可以更好地控制程序所使用的資源,因為你可以控制池中的物件數量。
  • 增加資源的重用:可以更好地重用資源,避免不必要的浪費。
  • 靈活性:物件池可以根據需要配置和調整,以適應不同的系統需求和性能要求。
  • 易於監控:可以更容易地監控物件池的狀態和性能,以進行優化和調整。

缺點

  • 複雜度增加
    • 實現複雜:物件池模式增加了系統的複雜度,因為需要實現和管理池的邏輯。
    • 錯誤處理:需要小心處理物件池中的錯誤和異常,以避免資源洩露和不穩定的狀態。
  • 資源管理的挑戰
  • 資源過剩:如果池中的物件數量配置得太多,可能會導致資源浪費。
  • 對象狀態管理:需要確保物件在返回池中時處於一個合適的狀態,避免因為錯誤的狀態管理而導致問題。

Conclusion

Code

在程式方面,我們學到了list物件的用法。在這次範例中,我們在 Acquire() 中使用了Append()來做成員刪減list中第一個物件的作業。並在Release() 中展示了如何在刪除特定位置的成員。

UML

在這次的模型中,我們看到了一個新的UML圖示:
https://ithelp.ithome.com.tw/upload/images/20230905/201150824ZHxJfN1z1.jpg

這個圖示的名字為:”聚合“,如同上下屬的關係。
舉個例子🌰,一間公司是許多部門組合而成的,那麼他們就是屬於聚合關係,如圖
https://ithelp.ithome.com.tw/upload/images/20230905/20115082DmArBVK09B.jpg

Disign Pattern

在此篇文章中,我們理解了物件持模式的運作原理,並將其雛形實作完成。
下一篇章中也是以筆電代工廠為例將此模式中應用至情境。


上一篇
Prototype Pattern - 實際應用
下一篇
 Composite Pattern - 組合模式
系列文
掘地土撥鼠的設計歷險記11
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言