Fundamentals 7 min read

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.

Nullbody Notes
Nullbody Notes
Nullbody Notes
Factory Method Pattern in Go: A Foodie's Take on Object Creation

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 nut

Go’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 nut

Because 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

Factory Method illustration
Factory Method illustration
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsGoDependency InversionFactory MethodSimple FactorySingle Responsibility
Nullbody Notes
Written by

Nullbody Notes

Go backend development, learning open-source project source code together, focusing on simplicity and practicality.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.