golang吧 关注:6,321贴子:14,520
  • 7回复贴,共1

抽象工厂模式通用方法中增加缓存机制

只看楼主收藏回复

向大佬们求助
需求:在通用工厂和通用产品中增加缓存机制,根据缓存使具体工厂和具体产品沿用,比如通用工厂AbstractHardwareAbstractionLayer对GetProcessor加缓存机制,一分钟后过期,那么具体工厂LinuxHardwareAbstractionLayer中的GetProcessor以及其他具体工厂都应该在一分钟后过期,再次获取时,重新查询。通用产品同理,通用产品AbstractCentralProcessor对GetMaxFreq加缓存机制,一分钟后过期,那么具体产品LinuxCentralProcessor中的GetMaxFreq以及其他具体产品(WindowsCentralProcessor中的GetMaxFreq...)都应该在一分钟后过期,再次获取
抽象工厂
type HardwareAbstractionLayer interface {
GetProcessor() CentralProcessor
}
抽象产品
type CentralProcessor interface {
GetMaxFreq() int64
}
通用工厂,实现通用工厂方法
type AbstractHardwareAbstractionLayer struct{}
func (l *AbstractHardwareAbstractionLayer) GetProcessor() CentralProcessor {
return nil
}
具体工厂
type LinuxHardwareAbstractionLayer struct {
*AbstractHardwareAbstractionLayer
}
func (l *LinuxHardwareAbstractionLayer) GetProcessor() CentralProcessor {
cpu := new(LinuxCentralProcessor)
return cpu
}
通用产品,实现通用产品方法
type AbstractCentralProcessor struct{}
func (l *AbstractCentralProcessor) GetMaxFreq() int64 {
return -1
}
具体产品
type LinuxCentralProcessor struct {
*AbstractCentralProcessor
}
func (p *LinuxCentralProcessor) GetMaxFreq() int64 {
log.Println("queryMaxFreq called")
return rand.Int63()
}
缓存工具
type memoize struct {
sync.RWMutex
value interface{}
expirationTime time.Time
}
func Memoize(original func() interface{}) func() interface{} {
return MemoizeWithExpiration(original, -1)
}
func MemoizeWithExpiration(original func() interface{}, ttl time.Duration) func() interface{} {
m := &memoize{}
return func() interface{} {
m.RLock()
if ttl >= 0 && time.Now().Before(m.expirationTime) && m.value != nil {
defer m.RUnlock()
return m.value
}
m.RUnlock()
m.Lock()
defer m.Unlock()
if ttl >= 0 && time.Now().Before(m.expirationTime) && m.value != nil {
return m.value
}
m.value = original()
if ttl >= 0 {
m.expirationTime = time.Now().Add(ttl)
} else {
m.expirationTime = time.Time{}
}
return m.value
}
}
func DefaultExpiration() time.Duration {
return time.Minute
}


IP属地:北京1楼2024-09-20 11:20回复
    为什么会这么复杂?go一般不会写这么长的变量名。你是想在不同的系统获取CPU频率,然后得到的结果缓存一个分钟是吧。写个接口叫 hardwareInfoGetter,在写个具体实现结构体,LinuxHardwareInfo,结构体加个cache和上一次获取的time字段不就行了吗。


    IP属地:浙江来自Android客户端5楼2024-09-20 13:20
    收起回复
      没看懂是要干嘛,不过根据楼上说的,如果只是读取cpu时间的话,貌似做缓存也没多大必要,因为开销确实小


      IP属地:广东来自Android客户端6楼2024-09-20 13:32
      回复
        你的代码感觉像是horrible 的Java。为什么要将变量名叫AbstractHardwareAbstractionLayer?为什么会这么长?为什么命名CentralProcessor?好像有个简写是CPU?


        IP属地:浙江来自Android客户端7楼2024-09-20 13:33
        回复
          我的想法是如果你就支持两个平台的话那就这么最简单的来就行了。如果你真的写不了一点重复的代码的话,你可以写一个结构体叫hardwareInfoManager,这个是一个具体的结构,内部有一个抽象的底层接口,一个CPU数据结构和上次获取的更新的时间,获取CPUinfo的时候判断一下时间,必要时用底层接口更新结构体。整个manager初始化的时候要么自己判断平台,要么外部参数指定平台,来初始化底层的这个操作系统相关的接口。你的场景是一个utils类型的小功能,工厂模式绝对过重了。


          IP属地:浙江来自Android客户端8楼2024-09-20 14:38
          回复
            如果是通过操作系统和架构区分的话,也可以用go:build的方式解决,比如你linux读取本机cpu信息肯定不可能用win的方式。这样的方法也不需要定义接口,直接调用函数就行了


            IP属地:广东来自Android客户端9楼2024-09-20 18:21
            回复