学习Go语言之抽象工厂模式
抽象工厂模式常用于程序适配多种数据库,以达到开放扩展关闭修改的原则。
首先需要有一个思想就是数据库表结构都是固定,但是每种数据库语言存在差异性,因此使用接口规范功能,各种数据库有自己不同的语言实现,业务中也是使用接口操作,运行时根据配置实例化各种数据库实现。好处是增加新的数据库时,只需要用新的数据库语言实现即可,不用修改原来的代码。部署程序时,只需要修改配置即可适配不同的数据库。
一,数据模型(Model层)
1 package Model 2 3 type User struct { 4 Id int 5 UID string 6 LoginName string 7 PassWord string 8 } 9 10 func (t *User) TableName() string { 11 return "User" 12 }
myProject/MyORM/Model/Product.go
1 package Model 2 3 type Product struct { 4 Id int 5 UID string 6 Name string 7 Price float64 8 } 9 10 func (t *Product) TableName() string { 11 return "Product" 12 }
二,接口定义(Interface层)
1 package Data 2 3 import ( 4 "myProject/MyORM/Model" 5 ) 6 7 type IUser interface { 8 Add(entity *Model.User) bool 9 Edit(entity *Model.User) Model.User 10 }
myProject/MyORM/Data/IProduct.go
1 package Data 2 3 import ( 4 "myProject/MyORM/Model" 5 ) 6 7 type IProduct interface { 8 Add(entity *Model.Product) bool 9 Edit(entity *Model.Product) Model.Product 10 }
myProject/MyORM/Data/IProvider.go
♥ 抽象工厂接口
1 package Data 2 3 type IProvider interface { 4 GetUser() IUser 5 GetProduct() IProduct 6 }
三,接口实现(DAL层)
♣ 注意:Go语言的接口实现是隐式的,无须让实现接口的类型写出实现了哪些接口。这个设计被称为非侵入式设计。在类型中添加与接口签名一致的方法就可以实现该方法。
1.SQL实现
myProject/MyORM/SqlData/SqlUser.go
1 package SqlData 2 3 import ( 4 "fmt" 5 "myProject/MyORM/Model" 6 ) 7 8 type SqlUser struct { 9 } 10 11 func (p *SqlUser) Add(entity *Model.User) bool { 12 fmt.Println("sql执行UserAdd") 13 return true 14 } 15 16 func (p *SqlUser) Edit(entity *Model.User) Model.User { 17 fmt.Println("sql执行UserEdit") 18 return *entity 19 }
myProject/MyORM/SqlData/SqlProduct.go
1 package SqlData 2 3 import ( 4 "fmt" 5 "myProject/MyORM/Model" 6 ) 7 8 type SqlProduct struct { 9 } 10 11 func (p *SqlProduct) Add(entity *Model.Product) bool { 12 fmt.Println("sql执行ProductAdd") 13 return true 14 } 15 16 func (p *SqlProduct) Edit(entity *Model.Product) Model.Product { 17 fmt.Println("sql执行ProductEdit") 18 return *entity 19 }
myProject/MyORM/SqlData/SqlProvider.go
♥ SQL工厂实现
1 package SqlData 2 3 import ( 4 "myProject/MyORM/Data" 5 ) 6 7 type SqlProvider struct { 8 } 9 10 func (p *SqlProvider) GetUser() Data.IUser { 11 return new(SqlUser) 12 } 13 14 func (p *SqlProvider) GetProduct() Data.IProduct { 15 return new(SqlProduct) 16 }
2.Mysql实现
myProject/MyORM/MysqlData/MysqlUser.go
1 package MysqlData 2 3 import ( 4 "fmt" 5 "myProject/MyORM/Model" 6 ) 7 8 type MysqlUser struct { 9 } 10 11 func (p *MysqlUser) Add(entity *Model.User) bool { 12 fmt.Println("mysql执行UserAdd") 13 return true 14 } 15 16 func (p *MysqlUser) Edit(entity *Model.User) Model.User { 17 fmt.Println("mysql执行UserEdit") 18 return *entity 19 }
myProject/MyORM/MysqlData/MysqlProduct.go
1 package MysqlData 2 3 import ( 4 "fmt" 5 "myProject/MyORM/Model" 6 ) 7 8 type MysqlProduct struct { 9 } 10 11 func (p *MysqlProduct) Add(entity *Model.Product) bool { 12 fmt.Println("mysql执行ProductAdd") 13 return true 14 } 15 16 func (p *MysqlProduct) Edit(entity *Model.Product) Model.Product { 17 fmt.Println("mysql执行ProductEdit") 18 return *entity 19 }
myProject/MyORM/MysqlData/MysqlProvider.go
♥ MYSQL工厂实现
1 package MysqlData 2 3 import ( 4 "myProject/MyORM/Data" 5 ) 6 7 type MysqlProvider struct { 8 } 9 10 func (p *MysqlProvider) GetUser() Data.IUser { 11 return new(MysqlUser) 12 } 13 14 func (p *MysqlProvider) GetProduct() Data.IProduct { 15 return new(MysqlProduct) 16 }
三,业务逻辑(BLL层)
myProject/MyORM/Service/Factory.go
1 package Service 2 3 import ( 4 "myProject/MyORM/Data" 5 "myProject/MyORM/MysqlData" 6 "myProject/MyORM/SqlData" 7 ) 8 // 设置配置 9 const db = "sql" 10 11 // 简单工厂方法,根据配置加载不同的实现库 12 func Provider() Data.IProvider { 13 switch db { 14 case "sql": 15 return new(SqlData.SqlProvider) 16 case "mysql": 17 return new(MysqlData.MysqlProvider) 18 default: 19 panic("无法映射配置的数据库") 20 } 21 }
myProject/MyORM/Service/UserService.go
1 package Service 2 3 import ( 4 "myProject/MyORM/Data" 5 "myProject/MyORM/Model" 6 ) 7 8 type UserService struct { 9 } 10 11 var user Data.IUser 12 13 func init() { 14 user = Provider().GetUser() 15 } 16 17 func (u *UserService) Add(entity *Model.User) bool { 18 return user.Add(entity) 19 } 20 21 func (u *UserService) Update(entity *Model.User) Model.User { 22 return user.Edit(entity) 23 }
myProject/MyORM/Service/ProductService.go
1 package Service 2 3 import ( 4 "myProject/MyORM/Data" 5 "myProject/MyORM/Model" 6 ) 7 8 type ProductService struct { 9 } 10 11 var product Data.IProduct 12 13 func init() { 14 product = Provider().GetProduct() 15 } 16 17 func (p *ProductService) Add(entity *Model.Product) bool { 18 return product.Add(entity) 19 } 20 21 func (p *ProductService) Update(entity *Model.Product) Model.Product { 22 return product.Edit(entity) 23 }
四,界面展示(UI层)
myProject/MyORM/main.go
1 package main 2 3 import ( 4 "myProject/MyORM/Model" 5 "myProject/MyORM/Service" 6 ) 7 8 func main() { 9 user := &Model.User{ 10 Id: 1, 11 UID: "12124545", 12 LoginName: "admin", 13 PassWord: "123454", 14 } 15 userService := new(Service.UserService) 16 userService.Add(user) 17 18 product := &Model.Product{ 19 Id: 1, 20 UID: "12124545", 21 Name: "苹果", 22 Price: 12.5, 23 } 24 productService := new(Service.ProductService) 25 productService.Update(product) 26 }