设计模式
设计模式1
23种设计模式
为什么需要函数选项模式
package main
import "fmt"
type dbOptions struct {
Host string
Port int
UserName string
Password string
DBName string
}
type Option func(*dbOptions)
// WithHost 定义一个函数选项 这个函数主要用来设置Host
func WithHost(host string) Option {
return func(o *dbOptions) {
o.Host = host
}
}
func NewOpts(options ...Option) dbOptions {
dbopts := &dbOptions{
Host: "127.0.0.1",
Port: 3306,
}
for _, option := range options {
option(dbopts)
}
return *dbopts
}
func main() {
opts := NewOpts(WithHost("192.168.0.1"))
fmt.Println(opts)
//函数选项大量运用
}
package main
import (
"sync"
"sync/atomic"
)
type DBPool struct {
Host string
Port int
UserName string
}
var lock sync.Mutex
var dbPoolIns *DBPool
var initialed uint32
// GetDBPool 有问题的方法,并发
// 加锁 功能上没有问题,但是性能不好(放到外面)
// 高并发下,有bug
// goroutine1进来,实例化化dbPoolIns = &DBPool{}进行到一半,goroutine2进来读取不为空了,返回dbPookIns
func GetDBPool() *DBPool {
if atomic.LoadUint32(&initialed) == 1 { //原子性解决
return dbPoolIns
}
lock.Lock()
defer lock.Unlock()
if initialed == 0 {
dbPoolIns = &DBPool{}
atomic.StoreUint32(&initialed, 1)
}
return dbPoolIns
}
var once sync.Once //运行一次就行了
func GetDBPool2() *DBPool {
once.Do(func() {
dbPoolIns = &DBPool{}
})
return dbPoolIns
}
func main() {
}
package main
import "fmt"
/*
在小明的学校,每一年开学都会发教材,
主要是包括语文书,数学书,英语书,还有各种练习试卷。
这一天,小明去领了三本教材,分别是语文书,数学书和英语书,老师忙不过来,指定某个同学去发书
同学都去这个同学这里去领书。这个同学就是工厂。
*/
type Book interface {
Name() string
}
type chineseBook struct {
name string
}
type mathBook struct {
name string
}
type englishBook struct {
name string
}
func (cb *chineseBook) Name() string {
return cb.name
}
func (mb *mathBook) Name() string {
return mb.name
}
func (eb *englishBook) Name() string {
return eb.name
}
func GetBook(name string) Book {
if name == "语文书" {
return &chineseBook{name: "语文书"}
} else if name == "数学书" {
return &mathBook{name: "数学书"}
} else if name == "英语书" {
return &englishBook{name: "英语书"}
}
return nil
}
func main() {
//暴露了结构体,这个实例化过程简单,实际开发中这个创建过程可能很复杂
//cb := &chineseBook{name: "语文书"}
fmt.Println(GetBook("语文书").Name())
fmt.Println(GetBook("数学书").Name())
}
package main
import "fmt"
/*
在小明的学校,每一年开学都会发教材,
主要是包括语文书,数学书,英语书,还有各种练习试卷。
这一天,小明去领了三本教材,分别是语文书,数学书和英语书,老师忙不过来,指定某个同学去发书
同学都去这个同学这里去领书。这个同学就是工厂。
*/
type Book interface {
Name() string
}
type Paper interface {
Name() string
}
type chineseBook struct {
name string
}
func (cb *chineseBook) Name() string {
return cb.name
}
type chinesePaper struct {
name string
}
func (cp *chinesePaper) Name() string {
return cp.name
}
type mathBook struct {
name string
}
func (mb *mathBook) Name() string {
return mb.name
}
type englishBook struct {
name string
}
func (eb *englishBook) Name() string {
return eb.name
}
// Person person具体指定的是某个类型的人,我现在想抽象出一个角色,这个角色就叫发书人
//type Person struct {
//}
// Assigner 发书人
type Assigner interface {
GetBook(name string) Book
GetPaper(name string) Paper
}
type assigner struct{}
func (ass *assigner) GetBook(name string) Book {
if name == "语文书" {
return &chineseBook{name: "语文书"}
} else if name == "数学书" {
return &mathBook{name: "数学书"}
} else if name == "英语书" {
return &englishBook{name: "英语书"}
}
return nil
}
func (ass *assigner) GetPaper(name string) Paper {
if name == "语文发书人" {
return &chinesePaper{name: "语文发书人"}
}
return nil
}
type chineseBookAssigner struct {
}
func (cba *chineseBookAssigner) GetBook(name string) Book {
if name == "语文书" {
return &chineseBook{name: "语文书"}
}
return nil
}
func main() {
var a assigner
fmt.Println(a.GetBook("语文书").Name())
fmt.Println(a.GetBook("数学书").Name())
var cba chineseBookAssigner
fmt.Println(cba.GetBook("语文书").Name())
fmt.Println(a.GetPaper("语文发书人").Name())
}