工厂模式
工厂方法创建设计模式允许创建对象,而无需指定将要创建的对象的确切类型。
代码示例中展示了如何使用一个后端数据存储类型,创建出一个具体的具体的存储类型。
package data
//定义一个具体的存储类型的接口.然后定义出不同的实现方法。
type Store interface {
open(string)(io.ReadWriteClose,err)
}
//MemoryStore存储的具体实现
type MemoryStore struct {
//Memory store的具体实现
path string
}
func (m MemoryStore)open(string)(io.ReadWriteClose,err){
//do something
}
type DiskStore struct{
//disks tore的具体实现
path string
}
//以上都需要定义出来不同的"工厂"里的"方法"的具体实现。
func NewMemoryStore(string){
//dosomething
return MemoryStore{string}
}
func NewDiskStore(string){
//do something
return DiskStore{string}
}
// 以上就是每个具体的实现方法的创建方法。
//--------定义一个工厂方法-------
type StoreType int
const (
MemoryStore StoreType = 1 << iota
DiskStore
TempStore
)
func NewStore(st StoreType,name string)Store{
switch st {
case MemoryStore:
return NewMemoryStore(name)
case DiskStore:
return NewDiskStore(name)
default :
return NewTmpStore(name)
}
}
工厂方法的使用
使用工厂方法,我们能够很自由快速的创建出不同的工厂方法,而不需要明确的知道里面的具体制作过程。而仅仅需要传递必要的参数给工厂即可。工厂自然能够根据提供的参数,在内部创建出我们需要的对象。而内部的这些内容对外部是隐藏的。且当创建的对象的属性变更时。
//这里使用工厂方法,仅传入一个具体的类型。不会涉及到具体某类方法在创建的时候,还需要加入什么参数。具体的创建方法被隐藏在了工厂方法内部。
s,_ := data.NewStore(data.MemmoryStore)
f,_ := s.open("filename")
n,_ := f.Write([]bytes("data"))
defer f.Close()
小结:
工厂方法的核心就是,通过工厂能够制造出不同类型的同一类东西。(例如制造鞋子,可以有运动鞋,跑步鞋等。)对于外部的用户就可以仅仅只暴露一个方法,就是制造鞋子,提供一个必须的参数。当然鞋子的具体制作方法被隐藏在了工厂方法里面。当然每种类型都可以有自己单独的制造方法。
对象池模式
对象池模式用于根据需求的期望,创建准备和保留多个实例在对象池中。
代码示例:
//这里定义池是一个chan。把chan作为对象的容器。当然也完全可以考虑使用对象切片等方式来作为对象池容器。
type Pool chan *object
func NewPool(n int)*Pool{
p := make(Pool,n) //定义出来一个池容器
for i=0;i<n;i++{
p <- new(object) //创建对象,把对象放入容器中。
}
return &
}
使用对象池
//创建一个池
p := NewPool(2)
//使用池中的对象。由于对象池是使用chan作为容器。所以这里取池中的对象的方式为select等待chan中有对象加入,然后才从池中实时取出对象,并使用对象完成一些任务。
//这里如果池是使用其他作为容器,如切片。那么我们这里取出对象的方式就不同。可以使用下标,或循环的方式来取对象出来。
select {
case obj <- p :
obj.Dosomething()
default:
dosomething()
return
}
小结:
- 对象池在对象初始化比对象维护更昂贵的情况下很有用。
- 如果需求是以突发形式,而不是平稳的形式存在。那么每次去维护对象会比对象池会更好。
- 对对象池中的对象做了预处理,在性能上会一定积极的影响。
对象池的核心就是创建出一个存放对象的容器。然后把需要的对象做一定的初始化后存入容器中。并在需要使用的时候,直接从池中取出。完成一部分的工作,最后可能需要对这个对象做处理,再放入对象池中。
对象池在很多的组件当中有体现。往往组件再做初始化的时候,就会帮我们创建出一定的对象池。而我们在使用的时候,会再由组件选择其中的一个对象池进行使用。使用完成后,再又组件完成清理工作,并放回到对象池当中。
单实例模式
单例创建设计模式将限制某个类型仅仅能够实例化出一个对象。
代码示例:
package singleton
type singleton map[string]string //用来存储实例化对象的容器。也可以是某个具体的结构体体。
/*
type singleStruct {
name string
}
*/
var (
once sync.Once
instance singleton
)
func New()singleton{
once.Do(func(){
instance = make(singleton)
})
//以上部分仅仅会给执行一次。而当不会被执行的时候。还需要return是能够正常完成的。所以就需要instanc是已经初始化声明过的。
return instance
}
//--------单示例的使用-----
s := singleton.New()
s['this'] = "that"
s2 := singleton.New()
ftm.Print("this is :",s2["this"])
小结:
单例模式会用来表示一个全局状态,并且大多数时候会降低可测试性。