golang抽象工厂模式

93 阅读2分钟

抽象工厂模式通常基于一组工厂方法,它能创建一系列相关的对象。在设计良好的代码中,每个类仅负责一件事,如果一个类与多种类型产品交互,就可以考虑将工厂方法抽取到独立的工厂类或者抽象工厂中。

实现

以 上传图片/视频到不同的云存储 为例:

定义云存储的接口

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())
	
}

总结

如果代码需要与多个不同系列的产品进行交互,出于对扩展性的考虑,或者无法提前获取相关信息,不希望代码基于具体的产品进行构建,使用抽象工厂模式。 优点: 符合单一职责和开闭原则。确保同一工厂生产的产品是一致的,相互匹配的。缺点:增加代码复杂度。