go中常用的设计模式。

简单工厂

 1package main
 2
 3import "fmt"
 4
 5//中国人,你好
 6//英国人 ,hello
 7type API interface{//接口
 8	Say(name string)string
 9}
10
11func NewAPI(str string)API{
12	if str=="en"{
13		return &English{}
14	}else if str=="cn"{
15		return &Chinese{}
16	} else{
17		return nil
18	}
19}
20
21
22type  Chinese struct{}
23func (*Chinese)	Say(name string)string{
24	return "你好"+name
25}
26
27type  English struct{}
28func (*English)	Say(name string)string{
29	return "hello"+name
30}
31
32type  Japanese struct{}
33func (*Japanese)	Say(name string)string{
34	return "鬼子你好"+name
35}
36
37func main11(){
38	api:=NewAPI("cn")
39	server:=api.Say("张海涛")
40	fmt.Println(server)
41}
42func main12(){
43	api:=NewAPI("en")
44	server:=api.Say("Alex")
45	fmt.Println(server)
46}

函数选项模式

这个是go语言比较特殊的。有些开源项目如grpc的链接也是用了这个模式.

 1package main
 2
 3import "fmt"
 4
 5type DbConfig struct {
 6	host     string
 7	port     int
 8	password string
 9	username string
10	printLog bool
11}
12
13type Option func(config *DbConfig)
14
15func WithPrintLog() Option {
16	return func(config *DbConfig) {
17		config.printLog = true
18	}
19}
20
21func NewDbConfig(Options ...Option) *DbConfig {
22	//默认值
23	var config = &DbConfig{
24		host: "127.0.0.1",
25		port: 3306,
26	}
27	for _, option := range Options {
28		option(config)
29	}
30	return config
31}
32
33func main() {
34	dbConfig := NewDbConfig(WithPrintLog())
35	fmt.Printf("%+v", dbConfig)
36}

单例模式

官方提供了sync.Once ,直接加锁实现也可以,就是性能不高。

 1package main
 2
 3import (
 4	"fmt"
 5	"sync"
 6	"time"
 7)
 8
 9type DbConfig struct {
10	host     string
11	port     int
12	password string
13	username string
14	printLog bool
15}
16
17type Option func(config *DbConfig)
18
19func WithPrintLog() Option {
20	return func(config *DbConfig) {
21		config.printLog = true
22	}
23}
24
25func NewDbConfig(Options ...Option) *DbConfig {
26	//默认值
27	var config = &DbConfig{
28		host: "127.0.0.1",
29		port: 3306,
30	}
31	for _, option := range Options {
32		option(config)
33	}
34	return config
35}
36
37var once sync.Once
38var dbConfig *DbConfig
39
40func GetDbConfig() *DbConfig {
41	once.Do(func() {
42		dbConfig = NewDbConfig(WithPrintLog())
43		fmt.Printf("%+v\n", dbConfig)
44	})
45	return dbConfig
46}
47
48func main() {
49	go func() {
50		fmt.Printf("%p\n", GetDbConfig())
51	}()
52	go func() {
53		fmt.Printf("%p\n", GetDbConfig())
54	}()
55	go func() {
56		fmt.Printf("%p\n", GetDbConfig())
57	}()
58	time.Sleep(time.Second)
59}

责任链模式

责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者 。

如gin 的中间件实现。

 1type Context struct {
 2    // ...
 3
 4    // handlers 是一个包含执行函数的数组
 5    // type HandlersChain []HandlerFunc
 6	handlers HandlersChain
 7    // index 表示当前执行到哪个位置了
 8	index    int8
 9
10    // ...
11}
12
13// Next 会按照顺序将一个个中间件执行完毕
14// 并且 Next 也可以在中间件中进行调用,达到请求前以及请求后的处理
15// Next should be used only inside middleware.
16// It executes the pending handlers in the chain inside the calling handler.
17// See example in GitHub.
18func (c *Context) Next() {
19	c.index++
20	for c.index < int8(len(c.handlers)) {
21		c.handlers[c.index](c)
22		c.index++
23	}
24}

原型模式

主要用于快速复制复杂的对象 。 结合注册树。

 1package main
 2
 3import "fmt"
 4
 5//原型对象需要实现的接口
 6//map  map[""1232]=1232
 7//拷贝原有的对象
 8
 9
10type Cloneable interface{
11	Clone() Cloneable
12}
13
14//原型对象的类
15type PrototypeManger struct{
16	prototypes map[string]Cloneable
17}
18//构造初始化
19func NewPrototypeManger() * PrototypeManger{
20	return &PrototypeManger{make(map[string]Cloneable)}
21}
22//抓取
23func (p* PrototypeManger)Get(name string)Cloneable{
24	return p.prototypes[name]
25}
26//设置
27func (p* PrototypeManger)Set(name string, prototype Cloneable){
28	p.prototypes[name]=prototype
29}
30
31
32type Type1 struct{
33	name string
34}
35func (t*Type1)Clone() Cloneable{
36	//tc:=*t
37	//return &tc 深复制
38	return t
39}
40
41type Type2 struct{
42	name string
43}
44func (t*Type2)Clone() Cloneable{
45	tc:=*t //开辟内存新建变量,存储指针指向的内容
46	return &tc //返回地址
47}
48
49
50
51func main(){
52	mgr:=NewPrototypeManger()
53	t1:=&Type1{name:"type1"}
54	mgr.Set("t1",t1)
55	t11:=mgr.Get("t1")
56	t22:=t11.Clone()//复制
57	if t11==t22{
58		fmt.Println("浅复制")
59	}else{
60		fmt.Println("深复制")
61	}
62}

装饰器模式

装饰器模式是指不在改变现有对象结构的情况下,动态地给改对象增加一些功能的设计模式

实例增加 装饰的组建(如手机基础组件) . 在实例进行执行功能的时候,自动加装饰的部分代码进行执行

 1package decorator
 2
 3type Phone interface {
 4	GetPrice() float32
 5}
 6
 7//装饰
 8type Decorator struct {
 9	Phone Phone
10}
11
12//装饰设置组件方法
13func (d *Decorator) SetComponent(c Phone) {
14	d.Phone = c
15}
16
17//装饰方法
18func (d *Decorator) GetPrice() {
19	if d.Phone != nil {
20		d.Phone.GetPrice()
21	}
22}
23
24//基础零件
25type BaseParts struct {
26}
27
28//获取基础零件手机价格
29func (p *BaseParts) GetPrice() float32 {
30	return 2000
31}
32
33type IPhone struct {
34	Decorator
35}
36
37//获取IPhone价格
38func (c *IPhone) GetPrice() float32 {
39	phonePrice := c.Phone.GetPrice()
40	return phonePrice + 6000
41}
42
43type Xiaomi struct {
44	Decorator
45}
46
47//小米手机的价格
48func (c *Xiaomi) GetPrice() float32 {
49	phonePrice := c.Phone.GetPrice()
50	return phonePrice + 1000
51}
 1package decorator
 2
 3import (
 4	"fmt"
 5	"testing"
 6)
 7
 8func TestDecorator(t *testing.T) {
 9	//具体零件
10	phone := &BaseParts{}
11	fmt.Printf("基础零件的价格为:%f\n", phone.GetPrice())
12
13	//定义添加IPhone手机
14	iPhone := &IPhone{}
15	iPhone.SetComponent(phone)
16	fmt.Printf("苹果的价格为:%f\n", iPhone.GetPrice())
17
18	//定义添加Xiaomi手机
19	xiaomi := &Xiaomi{}
20	xiaomi.SetComponent(phone)
21	fmt.Printf("小米的价格为:%f\n", xiaomi.GetPrice())
22
23}