提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
抽象工厂模式经常以工厂方法的方式实现。
如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。
在上篇文章的基础上,小米和华为都要生产手表的时候,我们应该怎么编码?
// factory.go
// 抽象工厂,包含一系列创建产品的抽象
type IFactory interface {
makePhone() IPhone
makeWatch() IWatch
}
func GetFactory(tp string) IFactory {
if tp == "xiaomi" {
return &Xiaomi{}
} else if tp == "huawei" {
return &Huawei{}
} else {
panic("not found type")
}
return nil
}
// 具体工厂类
type Xiaomi struct{}
func (x *Xiaomi) makePhone() IPhone {
return &Phone{
name: "xiaomi 12",
price: 3999,
}
}
func (x *Xiaomi) makeWatch() IWatch {
return &Watch{
name: "miWatch",
price: 299,
}
}
type Huawei struct{}
func (h *Huawei) makePhone() IPhone {
return &Phone{
name: "iPhone 14",
price: 6999,
}
}
func (h *Huawei) makeWatch() IWatch {
return &Watch{
name: "apple watch",
price: 2999,
}
}
// product.go
// 抽象产品
type IPhone interface {
setPhoneName(name string)
setPhonePrice(price float64)
getPhoneName() string
getPhonePrice() float64
}
type IWatch interface {
setWatchName(name string)
setWatchPrice(price float64)
getWatchName() string
getWatchPrice() float64
}
// 具体产品类
type Phone struct {
name string
price float64
}
func (g *Phone) setPhoneName(name string) {
g.name = name
}
func (g *Phone) getPhoneName() string {
return g.name
}
func (g *Phone) setPhonePrice(price float64) {
g.price = price
}
func (g *Phone) getPhonePrice() float64 {
return g.price
}
type Watch struct {
name string
price float64
}
func (w *Watch) setWatchName(name string) {
w.name = name
}
func (w *Watch) getWatchName() string {
return w.name
}
func (w *Watch) setWatchPrice(price float64) {
w.price = price
}
func (w *Watch) getWatchPrice() float64 {
return w.price
}
// main.go
// 客户端调用
func main() {
xiaomiFactory := GetFactory("xiaomi")
xiaomiPhone := xiaomiFactory.makePhone()
xiaomiWatch := xiaomiFactory.makeWatch()
huaweiFactory := GetFactory("huawei")
huaweiPhone := huaweiFactory.makePhone()
huaweiWatch := huaweiFactory.makeWatch()
printPhoneDetails(xiaomiPhone)
printWatchDetails(xiaomiWatch)
printPhoneDetails(huaweiPhone)
printWatchDetails(huaweiWatch)
}
func printPhoneDetails(p IPhone) {
fmt.Printf("Phone: %s", p.getPhoneName())
fmt.Println()
fmt.Printf("Price: %.2f", p.getPhonePrice())
fmt.Println()
fmt.Println("---------------------------")
}
func printWatchDetails(w IWatch) {
fmt.Printf("watch: %s", w.getWatchName())
fmt.Println()
fmt.Printf("Price: %.2f", w.getWatchPrice())
fmt.Println()
fmt.Println("---------------------------")
}
output:
Phone: xiaomi 12
Price: 3999.00
---------------------------
watch: miWatch
Price: 299.00
---------------------------
Phone: iPhone 14
Price: 6999.00
---------------------------
watch: apple watch
Price: 2999.00
---------------------------