设计模式——单例模式

什么是单例模式?

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

实现

var (
    p *Pet
    once sync.Once
)

func GetInstance() *Pet {
    return p
}

func init()  {
    once.Do(func() {
        p = &Pet{}
    })
}

type Pet struct {
    name string
    age int
    mux sync.Mutex
}

func (this *Pet)SetName(name string) {
    this.mux.Lock()
    defer this.mux.Unlock()
    this.name = name
}

func (this *Pet)GetName() string {
    this.mux.Lock()
    defer this.mux.Unlock()
    return this.name
}

func (this *Pet)SetAge(age int) {
    this.mux.Lock()
    defer this.mux.Unlock()
    this.age = age
}

func (this *Pet)GetAge() int {
    this.mux.Lock()
    defer this.mux.Unlock()
    return this.age
}

func (this *Pet)IncrementAge() {
    this.mux.Lock()
    defer this.mux.Unlock()
    this.age++
}
func TestGetInstance(t *testing.T) {
    p := GetInstance()
    p.SetAge(10)
    p.IncrementAge()
    fmt.Println("p 的 Age现在是", p.GetAge())
    
    q := GetInstance()
    q.IncrementAge()
    fmt.Println("q 的 Age现在是", q.GetAge())
}
/*
=== RUN   TestGetInstance
p 的 Age现在是 11
q 的 Age现在是 12
--- PASS: TestGetInstance (0.00s)
PASS
*/

优点

  • 内存中只有一个实例,减少了内存开支,尤其一个对象需要频繁地创建销毁,而此时性能又无法优化时,单例模式的优势就非常明显;
  • 避免对资源的多重占用(比如写文件操作,只有一个实例时,避免对同一个资源文件同时写操作),简单来说就是对唯一实例的受控访问。

缺点

  • 没有接口,不能继承,与单一职责冲突。

使用场景

  • 要求生成唯一序列号的环境;
  • 在整个项目中有一个共享访问点或共享数据(如web页面上的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来即可);
  • 创建一个对象需要消耗的资源过多时(如访问I/O和数据库等资源)。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。