likes
comments
collection
share

go如何实现单例模式和工厂模式?

作者站长头像
站长
· 阅读数 11

什么是设计模式

设计模式是对在软件设计中普遍存在的各种问题,按最佳实践的方式提出一种的解决方案,是处理这类问题的一个经典模式,通俗说就是软件设计的经典“套路”,使用设计模式可以提高代码的复用性和可读性。

总体上,设计模式可以分为3大类共24种经典的设计方案

go如何实现单例模式和工厂模式?

创建型模式

创建型模式提供对象创建这种场景的最佳实践,通过隐藏对象的创建逻辑,达到解耦的目的

单例模式

单系统中只需要维护一个全局的实例时,单例模式就派上用场了,例如整项目中只有一个数据库实例。单例模式有利于减少系统开销,避免多个实例产生冲突。

单例模式分为两种模式懒汉方式和饿汉方式,两者的区别在于创建的时机,顾名思义,饿汉方式,因为饿所以迫不及待的包加载的时候就创建对象,而懒汉方式就比较懒了,要等到使用的时候才会创建对象,当然是在第一次使用的时候创建了

  • 饿汉方式
package singleton

type singleton struct {

}

var ins *singleton = &singleton{}

func GetIns() *singleton {

   return ins
}

因为是在实例所在包被导入时就创建,未被使用就提前创建浪费内存,所以懒汉方式在开源项目中较多使用,单需要注意由于它不是并发安全的,所以在实际使用中一定要加锁,为了提高性能只需要在创建对象的时候加锁,同时需要注意再锁内需要再次判断实例是否已经被创建,避免已经等待锁的线程,获得锁后重复创建实例

  • 懒汉方式
var ins *singleton

var mu sync.Mutex

func GetIns() *singleton {

   if ins == nil {

      mu.Lock()

      if ins != nil {

         return &singleton{}

      }

      mu.Unlock()

   }

   return ins

}

实际上,在go开发中借助系统sync包可以有更优雅的实现

import "sync"

type singleton struct {

}

var ins *singleton

var once sync.Once

func GetIns() *singleton {

   once.Do(func() {

      ins = &singleton{}

   })

   return ins

}

工厂模式

工厂模式是面向对象中创建对象常用的模式

  • 简单工厂模式

简单工厂模式又称为静态工厂方法模式,可以根据参数的不同返回不同的实例,使用者不需要关注创建的细节


type Gun struct {

   name string

   power int

}

func (g Gun) shot() {

   fmt.Sprintf("%s Shoots bullets with a firepower of %d", g.name, g.power)

}

func NewGun(name string, power int) *Gun {

   return &Gun{

      name: name,

      power: power,

   }

}
  • 抽象工厂模式

抽象工厂通过抽象出接口,与简单工厂相比返回的是接口而不是结构体,这样可以实现多个工厂函数来返回不同的接口实现而调用者不必关心对应的结构体,只需要关注所要调用的功能

type IGun interface {
   shot()
}

type Ak47 struct {
   name string

   power int
}

func (g Ak47) shot() {

   fmt.Sprintf("%s Shoots bullets with a firepower of %d", g.name, g.power)

}

func NewGun(name string, power int) IGun {

   return &Ak47{

      name: name,

      power: power,
   }

}
  • 工厂方法模式

在简单工厂模式中,如果要增加一种产品,就要修改创建产品的函数,在工厂方法模式中将对象创建从单一对象负责对象的实例化,变成由一群子类来负责具体类的实例化,从事实现创建过程的解耦


func NewGunFactory(gType string) func(name string, power int) Gun {

   return func(name string, power int) Gun {

      return Gun{

         gType: gType,

         name: name,

         power: power,

      }

   }

}

// 创建具有默认火力大小的工厂

func main() {

   newRifleGun := NewGunFactory("rifle")

   rifle := newRifleGun("ak47", 80)

   newSniperRifleGun := NewGunFactory("sniper rifle")

   sniperRifle := newSniperRifleGun("毛瑟", 100)

}

总结

设计模式是软件开发常用场景的参考样板,包含3大类共24种设计模式,本篇重点介绍了创建型模式下常用的2种设计模式。

go如何实现单例模式和工厂模式?

转载自:https://juejin.cn/post/7180277679369748539
评论
请登录