模式定义
提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类
类图
应用场景
程序需要处理不同系列的相关产品,但是你不希望它依赖于这些产品的具体类时可以使用抽象工厂模式
优点
1.可以确信你从工厂得到的产品彼此是兼容的;
2.可以避免具体产品和客户端代码之间的紧密耦合;
3.符合单一职责原则;
4.符合开闭原则
要点总结
- 如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以
- “系列对象”指的是在某一特定系列下的对象之间有相互依赖或作用的关系,不同系列的对象之间不能相互依赖
- Abstract Factory模式主要在于应对“新系列”的需求变动,其缺点在于难以应对“新对象”的需求变动
Go语言代码实现
工程目录
DaoFactory.go
package AbstractFactory
//记录接口
type OrderMainDao interface {
SaveOrderMain()
//SearchOrderMain()
}
//详情接口
type OrderDetailDao interface {
SaveOrderDetail()
}
//抽象工厂接口
type DaoFactory interface { //一系列相关接口
CreateOrderMainDao() OrderMainDao
CreateOrderDetailDao() OrderDetailDao
}
MYSQLDetailDaoFactory.go
package AbstractFactory
import "fmt"
type MYSQLMainDao struct {
}
func (*MYSQLMainDao) SaveOrderMain() {
fmt.Println("MYSQL main save")
}
type MYSQLDetailDao struct {
}
func (*MYSQLDetailDao) SaveOrderDetail() {
fmt.Println("MYSQL detail save")
}
MYSQLFactory.go
package AbstractFactory
//抽象工厂
type MYSQLFactory struct {
}
func (*MYSQLFactory) CreateOrderMainDao() OrderMainDao {
return &MYSQLMainDao{}
}
func (*MYSQLFactory) CreateOrderDetailDao() OrderDetailDao {
return &MYSQLDetailDao{}
}
OracleFactory.go
package AbstractFactory
//抽象工厂
type OracleFactory struct {
}
func (*OracleFactory) CreateOrderMainDao() OrderMainDao {
return &OracleMainDao{}
}
func (*OracleFactory) CreateOrderDetailDao() OrderDetailDao {
return &OracleDetailDao{}
}
OracleDetailDaoFactory.go
package AbstractFactory
import "fmt"
type OracleMainDao struct {
}
func (*OracleMainDao) SaveOrderMain() {
fmt.Println("Oracle main save")
}
type OracleDetailDao struct {
}
func (*OracleDetailDao) SaveOrderDetail() {
fmt.Println("Oracle detail save")
}
abstractFactory_test.go
package AbstractFactory
import "testing"
func TestMySqlFactory_CreateOrderMainDao(t *testing.T) {
var factory DaoFactory
factory = &MYSQLFactory{}
factory.CreateOrderMainDao().SaveOrderMain()
factory.CreateOrderDetailDao().SaveOrderDetail()
factory = &OracleFactory{}
factory.CreateOrderDetailDao().SaveOrderDetail()
factory.CreateOrderMainDao().SaveOrderMain()
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。