学习Go语言之抽象工厂模式

抽象工厂模式常用于程序适配多种数据库,以达到开放扩展关闭修改的原则。

首先需要有一个思想就是数据库表结构都是固定,但是每种数据库语言存在差异性,因此使用接口规范功能,各种数据库有自己不同的语言实现,业务中也是使用接口操作,运行时根据配置实例化各种数据库实现。好处是增加新的数据库时,只需要用新的数据库语言实现即可,不用修改原来的代码。部署程序时,只需要修改配置即可适配不同的数据库。

 

一,数据模型(Model层)

myProject/MyORM/Model/User.go
 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层)

myProject/MyORM/Data/IUser.go
 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 }

 

 

posted @ 2019-05-21 14:03  卓扬  阅读(751)  评论(0编辑  收藏  举报