抽象工厂模式通常基于一组工厂方法,它能创建一系列相关的对象。在设计良好的代码中,每个类仅负责一件事,如果一个类与多种类型产品交互,就可以考虑将工厂方法抽取到独立的工厂类或者抽象工厂中。
实现
以 上传图片/视频到不同的云存储 为例:
定义云存储的接口
package main
type IYun interface {
uploadImg() IImg
uploadVideo() IVideo
}
不同的云厂商实现 img/video 行为
- 阿里云
package main
type Aliyun struct{}
func (a *Aliyun) uploadImg() IImg {
// println("AliYun uploadImg .... ")
return &AliYunImg{
Img: Img{
name: "aliyun",
path: "/ali/img/",
},
}
}
func (a *Aliyun) uploadVideo() IVideo {
return &AliYunVideo{
Video: Video{
name: "AliYunVideo",
path: "/AliYunVideo/video/",
size: 2123,
},
}
}
- 腾讯云
package main
type TencentYun struct{}
func (a *TencentYun) uploadImg() IImg {
// println("TencentYun uploadImg .... ")
return &TencentYunImg{
Img: Img{
name: "TencentYunImg",
path: "/TencentYunImg/img/",
},
}
}
func (a *TencentYun) uploadVideo() IVideo {
// println("TencentYun uploadVideo .... ")
return &TencentYunVideo{
Video: Video{
name: "TencentYun",
path: "/TencentYunImg/video/",
size: 1123,
},
}
}
定义 图片/视频 类接口
package main
// 图片
type IImg interface {
getName() string
getPath() string
}
// 视频类
type IVideo interface {
getName() string
getPath() string
getSize()
}
实现 图片 接口
package main
// 图片基类
type Img struct {
name string
path string
}
func (i *Img) getName() string {
return i.name
}
func (i *Img) getPath() string {
return i.path
}
// 阿里
type AliYunImg struct {
Img
}
// 腾讯
type TencentYunImg struct {
Img
}
实现 视频 接口
package main
// 视频基类
type Video struct {
name string
path string
size int
}
func (v *Video) getName() string {
return v.name
}
func (v *Video) getPath() string {
return v.path
}
func (v *Video) getSize() {
println(v.size)
}
type AliYunVideo struct {
Video
}
type TencentYunVideo struct {
Video
}
客户端调用
package main
// 简单的工厂
func sFactory(t int) IParse {
var obj IParse
switch t {
case 1:
obj = newJsonParser()
case 2:
obj = NewTomlParser()
default:
println("类型错误")
}
return obj
}
// 客户端调用
func client() {
aliyun := sFactory(1)
objImg := aliyun.uploadImg()
println(objImg.getName())
println(objImg.getPath())
}
总结
如果代码需要与多个不同系列的产品进行交互,出于对扩展性的考虑,或者无法提前获取相关信息,不希望代码基于具体的产品进行构建,使用抽象工厂模式。 优点: 符合单一职责和开闭原则。确保同一工厂生产的产品是一致的,相互匹配的。缺点:增加代码复杂度。