Composition over inheritance builds complex Go types by combining simpler components rather than deriving them from superclasses. This supports type-safe, expressive, and maintainable domain models. section 5.0
A Go implementation combines:
- Named types for measurements and units. section 5.6.2
- Structs and embedded types for domain-specific composition. section 5.0 section 5.6.2
- Collections, interfaces, and methods for shared behavior, scaling, conversion, and polymorphism. section 5.6.2
Recipe application
A recipe model composes measurements, ingredients, steps, and recipes. Interfaces and methods support scaling recipes, converting measurement systems, summarizing recipes, and creating grocery lists. section 5.0 section 5.6.2
// Example usage in main.
func main() {
recipe := Recipe{
Title: "Pancakes",
Yield: 2,
}
recipe.AddStep(Step{ #1
Description: "Mix dry ingredients",
Ingredients: []IngredientMeasurement{
{"Flour", MetricWeight{Measurement{Magnitude: 200, Unit: Gram}}},
{"Sugar", MetricWeight{Measurement{Magnitude: 50, Unit: Gram}}},
},
})
recipe.AddStep(Step{ #2
Description: "Add wet ingredients",
Ingredients: []IngredientMeasurement{
{"Milk", MetricWeight{Measurement{Magnitude: 300, Unit: Gram}}},
{"Egg", MetricWeight{Measurement{Magnitude: 50, Unit: Gram}}},
},
})
fmt.Println("Original Recipe:", recipe) #3
recipe.Scale(2) #4
fmt.Println("Scaled Recipe:", recipe) #5
list := CreateGroceryList(RecipeBox{recipe}) #6
fmt.Println("Grocery List:") #7
for ing, meas := range list {
fmt.Printf("%s: %.2f %s\n", ing, meas.Magnitude, meas.Unit) #8
}
}
The runnable usage listing creates a pancake recipe, adds ingredient steps, scales the recipe, prints both versions, and generates a grocery list. section 5.6.2

