仍然是汉堡的故事,在Golang设计模式-创建型-简单工厂 一文中,我们提到简单工厂的缺点之一是当产品种类较多时,工厂逻辑会变得非常复杂。哪里复杂,我们就分解哪里,这是分治法最朴素的思想,既然工厂逻辑复杂,那我们就把它分解一下吧。
工厂方法通过定义一个工厂基类和产品基类,并派生相应的工厂和产品子类的方式,实现由具体工厂生产具体产品的目标。
工厂系列的模式(简单工厂、工厂方法,以及我们马上将要介绍的抽象工厂)都有三要素,即产品、工厂和客户端。
与简单工厂相同,抽象产品即为汉堡,我们在此基础上派生出KFC和McDonalds的具体汉堡。
type Hamburger interface { Deliver() } type KfcHamburger struct{} func (h KfcHamburger) Deliver() { fmt.Println("This is a hamburger from KFC.\n") } type McdonaldsHamburger struct{} func (h McdonaldsHamburger) Deliver() { fmt.Println("This is a hamburger from McDonalds.\n") }与简单工厂模式由一个工厂完成所有产品的创建不同,工厂方法定义了一个抽象的工厂基类,并由派生的具体工厂负责对应产品的生产。
type HamburgerFactory interface { Create() Hamburger } type Kfc struct{} func (f Kfc) Create() Hamburger { return new(KfcHamburger) } type Mcdonalds struct{} func (f Mcdonalds) Create() Hamburger { return new(McdonaldsHamburger) }也就是通知工厂生产汉堡的人啦。
func main() { prefer := getPreferHamburger() var factory HamburgerFactory switch prefer { case "KFC": factory = new(Kfc) case "McDonalds": factory = new(Mcdonalds) default: fmt.Printf("%s not supported yet.\n", prefer) os.Exit(1) } hamburger := factory.Create() hamburger.Deliver() }我们来测试一下吧:
$ go build -o factory_method.bin factory_method.go $ ll factory_method.bin -rwxrwxr-x 1 pirlo pirlo 1672879 8月 30 21:39 factory_method.bin* $ ./factory_method.bin -prefer KFC This is a hamburger from KFC. $ ./factory_method.bin -prefer McDonalds This is a hamburger from McDonalds.使用类图表示如下:
完整代码:工厂方法
