go 常用设计模式-创建型模式

发布时间 2023-03-22 21:10:59作者: Marathon-Davis

本次分享的创建型模式主要包括:

  • 单例模式
  • 简单工厂模式
  • 工厂模式
  • 抽象共工厂模式

1.单例模式

package singleton

import "sync"

/*
创建型模式
*/

var (
	instance Singleton
	once sync.Once
)

type Singleton struct {}

func GetInstance() Singleton {
	once.Do(func() {
		instance = Singleton{}
	})

	return instance
}

func GetInstanceForNew() Singleton {
	return Singleton{}
}

# 除了使用once,也可以手动实现懒汉加载和饿汉加载模式

2.简单工厂模式

package simpleFactory

import "fmt"
/*
创建型模式
*/

type Product interface {
	Create()
}

type Product1 struct {}

func (p Product1) Create()  {
	fmt.Println("this is product1")
}

type Product2 struct {}

func (p Product2) Create()  {
	fmt.Println("this is product2")
}

type Factory struct {}

func (f Factory) Generate(name string) Product {
	switch name {
	case "product1":
		return Product1{}
	case "product2":
		return Product2{}
	default:
		return nil
	}
}

3.工厂模式

package factory

import "fmt"
/*
创建型模式
*/
type FoodKind int

const (
	MeatKind FoodKind = iota
	FruitKind
	VegetableKind
	NutKind
)

// Food interface
type Food interface {
	Eat()
}

// implement foods struct
type meat struct {}

func (m meat) Eat()  {
	fmt.Println("Eat meat")
}

type fruit struct {}

func (f fruit) Eat()  {
	fmt.Println("Eat fruit")
}

type vegetable struct {}

func (v vegetable) Eat()  {
	fmt.Println("Eat vegetable")
}

type nut struct {}

func (n nut) Eat()  {
	fmt.Println("Eat nut")
}

// define food factory
type Factory interface {
	NewFood(k FoodKind) Food
}

// implement factory
type MeatFactory struct {}

func (f MeatFactory) NewFood(k FoodKind) Food {
	return meat{}
}

type FruitFactory struct {}

func (f FruitFactory) NewFood(k FoodKind) Food {
	return fruit{}
}

type VegetableFactory struct {}

func (f VegetableFactory) NewFood(k FoodKind) Food {
	return vegetable{}
}

type NutFactory struct {}

func (f NutFactory) NewFood(k FoodKind) Food {
	return nut{}
}

4.抽象工厂模式

package abstractFactory

import "fmt"

/*
创建型模式
*/

// Food abstract interface
type Food interface {
	Eat()
}

// Drug abstract interface
type Drug interface {
	Take()
}

// Factory product food and drug
type Factory interface {
	NewFood() Food
	NewDrug() Drug
}

// real struct
// Food implement struct
type meat struct {}

func (m meat) Eat()  {
	fmt.Println("Eat meat")
}

type fruit struct {}

func (f fruit) Eat()  {
	fmt.Println("Eat fruit")
}

// Drug implement struct
type feverDrug struct {}

func (d feverDrug) Take()  {
	fmt.Println("Take feverDrug")
}

type coldDrug struct {}

func (d coldDrug) Take()  {
	fmt.Println("Take coldDrug")
}


// Factory implement struct
// first factory
type FirstFactory struct {}

func (f FirstFactory) NewFood() Food {
	return meat{}
}

func (f FirstFactory) NewDrug() Drug {
	return feverDrug{}
}

// second factory
type SecondFactory struct {}

func (f SecondFactory) NewFood() Food {
	return fruit{}
}

func (f SecondFactory) NewDrug() Drug {
	return coldDrug{}
}

5.对象池模式 = 单例 + 享元模式

参见gin.Context

package objectPool

import (
	"net/http"
	"sync"
)

var (
	// http 对象池
	ReqPool = sync.Pool{
		New: func() any {
			return http.Request{}
		},
	}
)

func operate()  {
	r1 := ReqPool.Get()
	r2 := ReqPool.Get()
	r3 := ReqPool.Get()

	ReqPool.Put(r1)
	ReqPool.Put(r2)
	ReqPool.Put(r3)
}

6.测试

package main

import (
	"fmt"
	"go-designMode/abstractFactory"
	"go-designMode/adapter"
	. "go-designMode/chainOfResponsibility"
	"go-designMode/decorator"
	factory2 "go-designMode/factory"
	"go-designMode/flyWeight"
	"go-designMode/objectPool"
	"go-designMode/observer"
	"go-designMode/proxy"
	"go-designMode/simpleFactory"
	"go-designMode/singleton"
	"go-designMode/strategy"
	"go-designMode/template"
	"go-designMode/visitor"
	"strings"
)

func main()  {
	fmt.Println(strings.Repeat("-", 10) + "创建型模式" + strings.Repeat("-", 10))
	// 1.singleton mode
	// call method
	fmt.Println("singleton mode testing...")
	s1 := singleton.GetInstance()
	s2 := singleton.GetInstance()
	s3 := singleton.GetInstanceForNew()

	fmt.Printf("s1 addr: %p\n", &s1)
	fmt.Printf("s2 addr: %p\n", &s2)
	fmt.Printf("s3 addr: %p\n", &s3)
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))

	// object pool = singleton + flyweight
	fmt.Println("objectPool mode testing...")
	r1 := objectPool.ReqPool.Get()
	r2 := objectPool.ReqPool.Get()
	r3 := objectPool.ReqPool.Get()

	objectPool.ReqPool.Put(r1)
	objectPool.ReqPool.Put(r2)
	objectPool.ReqPool.Put(r3)
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))

	// 2.simple factory mode
	// create Factory struct
	fmt.Println("simple factory mode testing...")
	factory := new(simpleFactory.Factory)
	// fan-in diff params
	p1 := factory.Generate("product1")
	p1.Create()

	// fan-in diff params
	p2 := factory.Generate("product2")
	p2.Create()
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))

	// 3.factory mode
	fmt.Println("factory mode testing...")
	factory2.MeatFactory{}.NewFood(factory2.MeatKind).Eat()
	factory2.FruitFactory{}.NewFood(factory2.FruitKind).Eat()
	factory2.VegetableFactory{}.NewFood(factory2.VegetableKind).Eat()
	factory2.NutFactory{}.NewFood(factory2.NutKind).Eat()
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))

	// 4.abstract factory mode
	fmt.Println("abstract factory mode testing...")
	first := &abstractFactory.FirstFactory{}
	first.NewFood().Eat()
	first.NewDrug().Take()

	second := &abstractFactory.SecondFactory{}
	second.NewFood().Eat()
	second.NewDrug().Take()
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))
}

参考文档: