Golang常用设计模式

颜均
2023-12-01

单例模式

// 使用once.Do可以确保 ins 实例全局只被创建一次,once.Do 函数还可以确保当同时有多个创建动作时,
// 只有一个创建动作在被执行。
type singleton03 struct {
}

var ins03 *singleton03
var once sync.Once

func GetInsOr03() *singleton03 {
	once.Do(func() {
		ins03 = &singleton03{}
	})
	return ins03
}

工厂模式

// 工厂方法模式
type Person03 struct {
	name string
	age  int
}

func NewPersonFactory(age int) func(name string) Person03 {
	return func(name string) Person03 {
		return Person03{
			name: name,
			age:  age,
		}
	}
}

func use() {
	newBaby := NewPersonFactory(1)
	baby := newBaby("john")
	fmt.Print(baby)

	newTeenager := NewPersonFactory(16)
	teen := newTeenager("jill")
	fmt.Print(teen)
}

策略模式

// 定义一个策略类
type IStrategy interface {
	do(int, int) int
}

// 策略实现:加
type add struct{}

func (*add) do(a, b int) int {
	return a + b
}

// 策略实现:减
type reduce struct{}

func (*reduce) do(a, b int) int {
	return a - b
}

// 具体策略的执行者
type Operator struct {
	strategy IStrategy
}

// 设置策略
func (operator *Operator) setStrategy(strategy IStrategy) {
	operator.strategy = strategy
}

// 调用策略中的方法
func (operator *Operator) calculate(a, b int) int {
	return operator.strategy.do(a, b)
}

模版模式

type Cooker interface {
	fire()
	cooke()
	outfire()
}

// 类似于一个抽象类
type CookMenu struct {
}

func (CookMenu) fire() {
	fmt.Println("开火")
}

// 做菜,交给具体的子类实现
func (CookMenu) cooke() {
}

func (CookMenu) outfire() {
	fmt.Println("关火")
}

// 封装具体步骤
func doCook(cook Cooker) {
	cook.fire()
	cook.cooke()
	cook.outfire()
}

type XiHongShi struct {
	CookMenu
}

func (*XiHongShi) cooke() {
	fmt.Println("做西红柿")
}

type ChaoJiDan struct {
	CookMenu
}

func (ChaoJiDan) cooke() {
	fmt.Println("做炒鸡蛋")
}

代理模式

type Seller interface {
	sell(name string)
}

// 火车站
type Station struct {
	stock int //库存
}

func (station *Station) sell(name string) {
	if station.stock > 0 {
		station.stock--
		fmt.Printf("代理点中:%s买了一张票,剩余:%d \n", name, station.stock)
	} else {
		fmt.Println("票已售空")
	}

}

// 火车代理点
type StationProxy struct {
	station *Station // 持有一个火车站对象
}

func (proxy *StationProxy) sell(name string) {
	fmt.Print("代理模式代理购票开始")
	proxy.station.sell(name)
	fmt.Print("代理模式代理购票结束")
}

选项模式

type Connection struct {
	addr    string
	cache   bool
	timeout time.Duration
}

const (
	defaultTimeout = 10
	defaultCaching = false
)

type options struct {
	timeout time.Duration
	caching bool
}

// Option overrides behavior of Connect.
type Option interface {
	apply(*options)
}

type optionFunc func(*options)

func (f optionFunc) apply(o *options) {
	f(o)
}

func WithTimeout(t time.Duration) Option {
	return optionFunc(func(o *options) {
		o.timeout = t
	})
}

func WithCaching(cache bool) Option {
	return optionFunc(func(o *options) {
		o.caching = cache
	})
}

// Connect creates a connection.
func Connect(addr string, opts ...Option) (*Connection, error) {
	options := options{
		timeout: defaultTimeout,
		caching: defaultCaching,
	}

	for _, o := range opts {
		o.apply(&options)
	}

	return &Connection{
		addr:    addr,
		cache:   options.caching,
		timeout: options.timeout,
	}, nil
}
 类似资料: