社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
李雷喜欢上了韩梅梅,他知道韩梅梅喜欢吃汉堡,于是就想买汉堡给她吃,但李雷不确定韩梅梅喜欢的是肯德基的汉堡还是麦当劳的汉堡,怎样帮助他呢?
最直观和最简单的实现就是if+else:
if prefer == "KFC" {
CreateKfcHamburger()
} else if prefer == "McDonalds" {
CreateMcdonaldsHamburger()
}
这个实现的问题是客户端关注了产品(汉堡)创建的全过程,且当扩展产品种类时需要修改客户端代码,违反了开放-封闭原则(对增加开放,对修改封闭)。
那么有没有更好的实现呢?
简单工厂通过定义一个工厂类,并提供创建产品的方法,将客户端从创建具体产品的尴尬局面中摆脱出来,客户端只需要告知产品类型即可,产品的具体创建由工厂完成。
以引例的汉堡工厂为例,产品即为汉堡,这个是一个抽象类型,根据产品类型的不同,我们分别定义两个具体产品,即肯德基的汉堡和麦当劳的汉堡:
type Hamburger interface {
Deliver()
}
type KfcHamburger struct{}
func (h KfcHamburger) Deliver() {
fmt.Println("This is a hamburger from KFC.")
}
type McdonaldsHamburger struct{}
func (h McdonaldsHamburger) Deliver() {
fmt.Println("This is a hamburger from McDonalds.")
}
汉堡工厂则根据需要生产指定类型的汉堡:
type HamburgerFactory struct{}
func (f HamburgerFactory) CreateHamburger(prefer string) Hamburger {
switch prefer {
case "KFC":
return new(KfcHamburger)
case "McDonalds":
return new(McdonaldsHamburger)
default:
return nil
}
}
于是,客户端再也不关注产品的具体创建过程了,而是告诉工厂“我需要什么,你就给我生产什么”:
func main() {
prefer := getPreferHamburger()
factory := new(creational.HamburgerFactory)
hamburger := factory.CreateHamburger(prefer)
if hamburger == nil {
fmt.Printf("%s not supported yet.n", prefer)
os.Exit(1)
}
hamburger.Deliver()
}
李雷作为客户,只需要获取韩梅梅喜欢的汉堡类型,然后让工厂生产就可以了:
$ ./simple_factory.bin -prefer KFC
This is a hamburger from KFC.
$ ./simple_factory.bin -prefer McDonalds
This is a hamburger from McDonalds.
使用类图表示如下:
完整代码: 简单工厂
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!