Factory Method Pattern in Go: A Foodie's Take on Object Creation
This article walks through implementing Simple Factory and Factory Method patterns in Go, showing how to encapsulate object creation with a Food interface, concrete types, and factory structs, and explains the pointer vs value implementation rules and design‑principle benefits.
Simple Factory
Define an enum FoodKind (values MeatKind, FruitKind, VegetableKind, NutKind) and an interface Food with method Eat(). Implement four concrete structs ( meat, fruit, vegetable, nut) in the same package. The first three have pointer‑receiver Eat methods, the last uses a value‑receiver:
type Food interface { Eat() }
type meat struct{}
func (t *meat) Eat() { fmt.Println("Eat meat") }
type fruit struct{}
func (t *fruit) Eat() { fmt.Println("Eat fruit") }
type vegetable struct{}
func (t *vegetable) Eat() { fmt.Println("Eat vegetable") }
type nut struct{}
func (t nut) Eat() { fmt.Println("Eat nut") }Factory function returns the appropriate implementation based on the enum:
func NewFood(k FoodKind) Food {
switch k {
case MeatKind:
return &meat{}
case FruitKind:
return &fruit{}
case VegetableKind:
return &vegetable{}
case NutKind:
return nut{} // value return is valid because <code>nut</code> implements <code>Food</code> with a value receiver
}
return nil
}Calling the function from main produces:
简单工厂模式
Eat meat
Eat fruit
Eat vegetable
Eat nutGo’s interface rules demonstrated: a pointer‑type implementation satisfies the interface only for pointer receivers; a value‑type implementation satisfies the interface for both pointer and value receivers.
Factory Method
Introduce a Factory interface that abstracts the creation method:
type Factory interface { NewFood(k FoodKind) Food }Implement four concrete factories, each returning the corresponding concrete type:
type MeatFactory struct{}
func (MeatFactory) NewFood(k FoodKind) Food { return &meat{} }
type FruitFactory struct{}
func (FruitFactory) NewFood(k FoodKind) Food { return &fruit{} }
type VegetableFactory struct{}
func (VegetableFactory) NewFood(k FoodKind) Food { return &vegetable{} }
type NutFactory struct{}
func (NutFactory) NewFood(k FoodKind) Food { return nut{} }Client code creates objects via the factories:
func main() {
fmt.Println("工厂方法模式")
method.MeatFactory{}.NewFood(method.MeatKind).Eat()
method.FruitFactory{}.NewFood(method.FruitKind).Eat()
method.VegetableFactory{}.NewFood(method.VegetableKind).Eat()
method.NutFactory{}.NewFood(method.NutKind).Eat()
}Program output matches the simple factory:
工厂方法模式
Eat meat
Eat fruit
Eat vegetable
Eat nutBecause each factory depends only on the abstract Food interface, the design follows the Single Responsibility Principle (each concrete struct handles only its own behavior) and the Dependency Inversion Principle (factories depend on the abstraction, not concrete types), which also supports the Open‑Closed Principle.
Source code repository: https://github.com/gofish2020/gopattern/tree/main/creator
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Nullbody Notes
Go backend development, learning open-source project source code together, focusing on simplicity and practicality.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
