Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Abstract Factory Pattern Medium

The abstract factory pattern provides an interface for creating families of related objects without specifying their concrete types. The client code works with factories and products through abstract interfaces, making it independent of the actual types being created.

Implementation

package factory

// Button and Checkbox are the abstract product interfaces.
type Button interface {
	Paint() string
}

type Checkbox interface {
	Check() string
}

// GUIFactory is the abstract factory interface.
type GUIFactory interface {
	CreateButton() Button
	CreateCheckbox() Checkbox
}

// --- Windows family ---

type WindowsButton struct{}

func (b *WindowsButton) Paint() string { return "Windows button" }

type WindowsCheckbox struct{}

func (c *WindowsCheckbox) Check() string { return "Windows checkbox" }

type WindowsFactory struct{}

func (f *WindowsFactory) CreateButton() Button     { return &WindowsButton{} }
func (f *WindowsFactory) CreateCheckbox() Checkbox  { return &WindowsCheckbox{} }

// --- Mac family ---

type MacButton struct{}

func (b *MacButton) Paint() string { return "Mac button" }

type MacCheckbox struct{}

func (c *MacCheckbox) Check() string { return "Mac checkbox" }

type MacFactory struct{}

func (f *MacFactory) CreateButton() Button     { return &MacButton{} }
func (f *MacFactory) CreateCheckbox() Checkbox  { return &MacCheckbox{} }

Usage

func BuildUI(f factory.GUIFactory) {
	button := f.CreateButton()
	checkbox := f.CreateCheckbox()

	fmt.Println(button.Paint())
	fmt.Println(checkbox.Check())
}

// The client code is decoupled from concrete product types.
BuildUI(&factory.WindowsFactory{})
// Windows button
// Windows checkbox

BuildUI(&factory.MacFactory{})
// Mac button
// Mac checkbox

Rules of Thumb

  • Use abstract factory when the system needs to be independent of how its products are created and composed.
  • Abstract factory is often implemented using factory methods under the hood.
  • If you only have one product family, you likely only need the simpler factory method pattern.