设计模式 1.创建型 1.1.工厂模式 核心思想 :不再提供一个统一的工厂类来创建所有产品,而是为每个产品提供一个对应的工厂。
这里拿数据库举例:
在web项目开发过程中,会涉及到数据库,假设这里有两种数据库,我们需要创建它们对应的连接,mysqlConnection,postgresConnection,编一个工厂方法的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 package CreationalPatternimport "fmt" type DBConnection interface { Connect() string Query(sql string ) string } type MysqlConnection struct { host string port int } func (m *MysqlConnection) Connect() string { return fmt.Sprintf("Connected to MySQL at %s:%d" , m.host, m.port) } func (m *MysqlConnection) Query(sql string ) string { return fmt.Sprintf("Query from MySQL using sql:%s" , sql) } type PostgresConnection struct { host string port int } func (p *PostgresConnection) Connect() string { return fmt.Sprintf("Connected to Postgres at %s:%d" , p.host, p.port) } func (p *PostgresConnection) Query(sql string ) string { return fmt.Sprintf("Query from Postgres using sql:%s" , sql) } type DBFactory interface { CreateConnection(host string , port int ) DBConnection } type MysqlFactory struct {}func (m MysqlFactory) CreateConnection(host string , port int ) DBConnection { return &MysqlConnection{host: host, port: port} } type PostgresFactory struct {}func (m PostgresFactory) CreateConnection(host string , port int ) DBConnection { return &PostgresConnection{host: host, port: port} }
main函数测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package mainimport ( "DesignPattern/CreationalPattern" "fmt" ) func main () { var factory CreationalPattern.DBFactory dbType := "mysql" switch dbType { case "mysql" : factory = CreationalPattern.MysqlFactory{} case "postgres" : factory = CreationalPattern.PostgresFactory{} default : panic ("Unsupported database type" ) } conn := factory.CreateConnection("10.100.167.1" , 8080 ) fmt.Println(conn.Connect()) fmt.Println(conn.Query("select * from abc" )) }
运行结果
1 2 Connected to MySQL at 10.100.167.1:8080 Query from MySQL using sql:select * from abc
1.2.抽象工厂模式 抽象工厂模式 提供了一种方式,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类。
这里使用Apple和xiaomi两家品牌举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 package CreationalPatternimport "fmt" type Phone interface { getName() string getPhoneCamera() string getSoc() string } type Laptop interface { getName() string getCpu() string getMemory() string } type Iphone struct { Name string Soc string PhoneCamera string } func NewIphone () *Iphone { return &Iphone{ Name: "iphone17" , Soc: "A18" , PhoneCamera: "sony" , } } func (i *Iphone) getName() string { return i.Name } func (i *Iphone) getPhoneCamera() string { return i.PhoneCamera } func (i *Iphone) getSoc() string { return i.Soc } type MacBookPro struct { Name string Cpu string Memory string } func NewMacBookPro () *MacBookPro { return &MacBookPro{ Name: "MacBookPro" , Cpu: "m5" , Memory: "32G" , } } func (m *MacBookPro) getName() string { return m.Name } func (m *MacBookPro) getCpu() string { return m.Cpu } func (m *MacBookPro) getMemory() string { return m.Memory } type MiPhone struct { Name string Soc string PhoneCamera string } func NewMiPhone () *MiPhone { return &MiPhone{ Name: "小米17" , Soc: "骁龙至尊版第五代" , PhoneCamera: "徕卡" , } } func (m *MiPhone) getName() string { return m.Name } func (m *MiPhone) getPhoneCamera() string { return m.PhoneCamera } func (m *MiPhone) getSoc() string { return m.Soc } type MiLaptop struct { Name string Cpu string Memory string } func NewMiLaptop () *MiLaptop { return &MiLaptop{ Name: "小米笔记本电脑" , Cpu: "AMD" , Memory: "32G" , } } func (m *MiLaptop) getName() string { return m.Name } func (m *MiLaptop) getCpu() string { return m.Cpu } func (m *MiLaptop) getMemory() string { return m.Memory } type ElectronicFactory interface { ProducePhone() Phone ProduceLaptop() Laptop } type AppleFactory struct { Name string } func (f *AppleFactory) ProducePhone() Phone { return NewIphone() } func (f *AppleFactory) ProduceLaptop() Laptop { return NewMacBookPro() } type XiaomiFactory struct { Name string } func (f *XiaomiFactory) ProducePhone() Phone { return NewMiPhone() } func (f *XiaomiFactory) ProduceLaptop() Laptop { return NewMiLaptop() } func ShowEcosystem (factory ElectronicFactory) { fmt.Println("*************生态系统************" ) phone := factory.ProducePhone() fmt.Println("手机信息:" ) fmt.Printf("name is %s\n" , phone.getName()) fmt.Printf("soc is %s\n" , phone.getSoc()) fmt.Printf("phonecamera is %s\n" , phone.getPhoneCamera()) laptop := factory.ProduceLaptop() fmt.Println("电脑信息:" ) fmt.Printf("name is %s\n" , laptop.getName()) fmt.Printf("cpu is %s\n" , laptop.getCpu()) fmt.Printf("memory is %s\n" , laptop.getMemory()) }
main函数测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package mainimport ( "DesignPattern/CreationalPattern" "fmt" ) func main () { appleFactory := &CreationalPattern.AppleFactory{ Name: "Apple" , } fmt.Printf("=============%s工厂=============\n" , appleFactory.Name) CreationalPattern.ShowEcosystem(appleFactory) xiaomiFactory := &CreationalPattern.XiaomiFactory{ Name: "Xiaomi" , } fmt.Printf("=============%s工厂=============\n" , xiaomiFactory.Name) CreationalPattern.ShowEcosystem(xiaomiFactory) }
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 =============Apple工厂============= *************生态系统************ 手机信息: name is iphone17 soc is A18 phonecamera is sony 电脑信息: name is MacBookPro cpu is m5 memory is 32G =============Xiaomi工厂============= *************生态系统************ 手机信息: name is 小米17 soc is 骁龙至尊版第五代 phonecamera is 徕卡 电脑信息: name is 小米笔记本电脑 cpu is AMD memory is 32G
1.3.原型模式 原型模式 是指通过复制现有对象 来创建新对象,而不是通过实例化类。当对象创建成本较高(如需要复杂计算、大量数据库查询)或者希望保持对象状态时特别有用。
下面使用深浅拷贝举例。
1.3.1.举例浅拷贝: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package CreationalPatternimport "fmt" type Cloneable interface { Clone() Cloneable } type Address struct { City string } type Person struct { Name string Age int Email string Address Address } func (p *Person) Clone() Cloneable { clone := &Person{ Name: p.Name, Age: p.Age, Email: p.Email, Address: p.Address, } return clone } func (p *Person) String() string { return fmt.Sprintf("Person{Name:%s, Age:%d, Email:%s, Address:%+v}" , p.Name, p.Age, p.Email, p.Address) }
main函数测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package mainimport ( "DesignPattern/CreationalPattern" "fmt" ) func main () { original := &CreationalPattern.Person{ Name: "Mike" , Age: 18 , Email: "mike@gmail.com" , Address: CreationalPattern.Address{ City: "上海" , }, } cloned := original.Clone().(*CreationalPattern.Person) fmt.Println("原始对象:" , original) fmt.Println("克隆对象:" , cloned) cloned.Name = "Tim" cloned.Address.City = "杭州" fmt.Println("\n修改后:" ) fmt.Println("原始对象:" , original) fmt.Println("克隆对象:" , cloned) }
运行结果
1 2 3 4 5 6 原始对象: Person{Name:Mike, Age:18, Email:mike@gmail.com, Address:{City:上海}} 克隆对象: Person{Name:Mike, Age:18, Email:mike@gmail.com, Address:{City:上海}} 修改后: 原始对象: Person{Name:Mike, Age:18, Email:mike@gmail.com, Address:{City:上海}} 克隆对象: Person{Name:Tim, Age:18, Email:mike@gmail.com, Address:{City:杭州}}
1.3.2.举例深拷贝: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 type DeepCloneable interface { DeepClone() DeepCloneable } type Employee struct { Name string Age int Department string PhoneNumber int Skills []Skill } type Skill struct { Name string Level int Tags []string } func (e *Employee) DeepClone() DeepCloneable { skillsCopy := make ([]Skill, len (e.Skills)) for i, skill := range e.Skills { tagsCopy := make ([]string , len (skill.Tags)) copy (tagsCopy, skill.Tags) skillsCopy[i] = Skill{ Name: skill.Name, Level: skill.Level, Tags: tagsCopy, } } return &Employee{ Name: e.Name, Age: e.Age, Department: e.Department, PhoneNumber: e.PhoneNumber, Skills: skillsCopy, } } func (e *Employee) String() string { return fmt.Sprintf("Employee{Name:%s, Age:%v, Deparment:%s, PhoneNumber:%v, Skills:%+v}" , e.Name, e.Age, e.Department, e.PhoneNumber, e.Skills) }
main函数测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package mainimport ( "DesignPattern/CreationalPattern" "fmt" ) func main () { original := &CreationalPattern.Employee{ Name: "John Smith" , Department: "Employee" , Age: 18 , PhoneNumber: 15599996666 , Skills: []CreationalPattern.Skill{ {Name: "golang" , Level: 3 , Tags: []string {"后端" , "IO操作" }}, {Name: "python" , Level: 5 , Tags: []string {"脚本" , "AI" }}, }, } clone := original.DeepClone() fmt.Printf("原对象: %+v\n" , original) fmt.Printf("克隆对象: %+v\n" , clone) clone.Name = "bob" clone.PhoneNumber = 11188887777 clone.Skills[0 ].Level = 6 fmt.Printf("修改后克隆对象: %+v\n" , original) fmt.Printf("Skills 切片地址是否相同: 原始%p 克隆%p\n" , &original.Skills, &clone.Skills) }
运行结果
1 2 3 4 原对象: Employee{Name:John Smith, Age:18, Deparment:Employee, PhoneNumber:15599996666, Skills:[{Name:golang Level:3 Tags:[后端 IO操作]} {Name:python Level:5 Tags:[脚本 AI]}]} 克隆对象: Employee{Name:John Smith, Age:18, Deparment:Employee, PhoneNumber:15599996666, Skills:[{Name:golang Level:3 Tags:[后端 IO操作]} {Name:python Level:5 Tags:[脚本 AI]}]} 修改后克隆对象: Employee{Name:John Smith, Age:18, Deparment:Employee, PhoneNumber:15599996666, Skills:[{Name:golang Level:3 Tags:[后端 IO操作]} {Name:python Level:5 Tags:[脚本 AI]}]} Skills 切片地址是否相同: 原始0xc00010a030 克隆0xc00010a080
1.4.生成器模式 生成器模式 将复杂对象构建的过程和表现形式分离
适用场景 :对象构建过程需要多个步骤,不同的表现形式
这里就用典型的配置构建来演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 package CreationalPatternimport ( "errors" "fmt" "time" ) type ServerConfig struct { Host string Port int Timeout time.Duration EnableSSL bool MaxConnections int } type ConfigBuilder struct { Config *ServerConfig Errors []error } func (cb *ConfigBuilder) Host(host string ) *ConfigBuilder { cb.Config.Host = host return cb } func (cb *ConfigBuilder) Port(port int ) *ConfigBuilder { if port < 1 || port > 65535 { cb.Errors = append (cb.Errors, errors.New("'port must be between 1 and 65535'" )) } cb.Config.Port = port return cb } func (cb *ConfigBuilder) Timeout(timeout time.Duration) *ConfigBuilder { cb.Config.Timeout = timeout return cb } func (cb *ConfigBuilder) EnableSSL(enableSSL bool ) *ConfigBuilder { cb.Config.EnableSSL = enableSSL return cb } func (cb *ConfigBuilder) MaxConnections(maxConnections int ) *ConfigBuilder { if maxConnections < 1 { cb.Errors = append (cb.Errors, errors.New("'max connections must be greater than zero'" )) } cb.Config.MaxConnections = maxConnections return cb } func (cb *ConfigBuilder) Build() (*ServerConfig, error ) { if len (cb.Errors) > 0 { return nil , fmt.Errorf("validation errors %v" , cb.Errors) } return cb.Config, nil } func NewConfigBuilder () *ConfigBuilder { return &ConfigBuilder{ Config: &ServerConfig{ Host: "localhost" , Port: 8080 , Timeout: time.Second * 15 , EnableSSL: false , MaxConnections: 10 , }, } }
main函数测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package mainimport ( "DesignPattern/CreationalPattern" "fmt" ) func main () { config, err := CreationalPattern.NewConfigBuilder(). Host("10.12.13.14" ). Port(6379 ). EnableSSL(true ). MaxConnections(10000 ). Build() if err != nil { panic (err) } fmt.Printf("%+v\n" , config) }
运行结果
1 &{Host:10.12.13.14 Port:6379 Timeout:15s EnableSSL:true MaxConnections:10000}
1.5.单例模式 单例模式 确保一个类只有一个实例,并提供一个访问该实例的全局访问点。
1.5.1.饿汉式示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 package CreationalPatternimport "time" type Singleton struct { Value int } var instance1 *Singleton = &Singleton{100 }func GetInstance1 () *Singleton { return instance1 }
main函数测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package mainimport ( "DesignPattern/CreationalPattern" "fmt" "sync" ) func main () { var wg sync.WaitGroup hashMap := sync.Map{} for i := 0 ; i < 10 ; i++ { wg.Add(1 ) go func (i int ) { defer wg.Done() inst := CreationalPattern.GetInstance1() hashMap.Store(inst, true ) fmt.Printf("goroutine %d got instance: %p value=%d\n" , i, inst, inst.Value) }(i) } wg.Wait() count := 0 hashMap.Range(func (key, value interface {}) bool { count++ return true }) fmt.Println("different instance count:" , count) }
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 goroutine 0 got instance: 0x7ff61d438580 value=100 goroutine 1 got instance: 0x7ff61d438580 value=100 goroutine 3 got instance: 0x7ff61d438580 value=100 goroutine 5 got instance: 0x7ff61d438580 value=100 goroutine 4 got instance: 0x7ff61d438580 value=100 goroutine 7 got instance: 0x7ff61d438580 value=100 goroutine 2 got instance: 0x7ff61d438580 value=100 goroutine 8 got instance: 0x7ff61d438580 value=100 goroutine 6 got instance: 0x7ff61d438580 value=100 goroutine 9 got instance: 0x7ff61d438580 value=100 different instance count: 1
1.5.2.懒汉式示例(线程不安全) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package CreationalPatternimport "time" type Singleton struct { Value int } var instance2 *Singletonfunc GetInstance2 () *Singleton { if instance2 == nil { time.Sleep(time.Millisecond) instance2 = &Singleton{200 } } return instance2 }
main函数测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package mainimport ( "DesignPattern/CreationalPattern" "fmt" "sync" ) func main () { var wg sync.WaitGroup hashMap := sync.Map{} for i := 0 ; i < 10 ; i++ { wg.Add(1 ) go func (i int ) { defer wg.Done() inst := CreationalPattern.GetInstance2() hashMap.Store(inst, true ) fmt.Printf("goroutine %d got instance: %p value=%d\n" , i, inst, inst.Value) }(i) } wg.Wait() count := 0 hashMap.Range(func (key, value interface {}) bool { count++ return true }) fmt.Println("different instance count:" , count) }
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 goroutine 8 got instance: 0xc000106060 value=200 goroutine 4 got instance: 0xc00000a090 value=200 goroutine 7 got instance: 0xc00000a060 value=200 goroutine 0 got instance: 0xc00000a068 value=200 goroutine 1 got instance: 0xc00000a038 value=200 goroutine 5 got instance: 0xc000106068 value=200 goroutine 3 got instance: 0xc000106090 value=200 goroutine 6 got instance: 0xc000184000 value=200 goroutine 2 got instance: 0xc000092000 value=200 goroutine 9 got instance: 0xc000288000 value=200 different instance count: 10
1.5.3.标准示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package CreationalPatternimport ( "sync" ) var ( instance3 *Singleton once sync.Once ) func GetInstance3 () *Singleton { once.Do(func () { instance3 = &Singleton{300 } }) return instance3 }
main函数测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package mainimport ( "DesignPattern/CreationalPattern" "fmt" "sync" ) func main () { var wg sync.WaitGroup hashMap := sync.Map{} for i := 0 ; i < 10 ; i++ { wg.Add(1 ) go func (i int ) { defer wg.Done() inst := CreationalPattern.GetInstance3() hashMap.Store(inst, true ) fmt.Printf("goroutine %d got instance: %p value=%d\n" , i, inst, inst.Value) }(i) } wg.Wait() count := 0 hashMap.Range(func (key, value interface {}) bool { count++ return true }) fmt.Println("different instance count:" , count) }
1 2 3 4 5 6 7 8 9 10 11 12 goroutine 1 got instance: 0xc00000a088 value=300 goroutine 2 got instance: 0xc00000a088 value=300 goroutine 3 got instance: 0xc00000a088 value=300 goroutine 4 got instance: 0xc00000a088 value=300 goroutine 5 got instance: 0xc00000a088 value=300 goroutine 6 got instance: 0xc00000a088 value=300 goroutine 7 got instance: 0xc00000a088 value=300 goroutine 8 got instance: 0xc00000a088 value=300 goroutine 0 got instance: 0xc00000a088 value=300 goroutine 9 got instance: 0xc00000a088 value=300 different instance count: 1