Factory Method Design Pattern in Go

1. Definition

The Factory Method Design Pattern provides an interface for creating objects in a superclass but allows subclasses to alter the type of created objects.

2. Problem Statement

Suppose you have a codebase that heavily depends on specific object types. If you wish to introduce a new type, modifying the codebase can be difficult and error-prone.

3. Solution

The Factory Method pattern solves this by defining a method for creating objects, which is then overridden by derived classes to produce the desired object, allowing for flexibility and easier expansion.

4. Real-World Use Cases

1. Payment gateway integrations where each provider has a different implementation.

2. GUI libraries where each OS provides a different button implementation.

5. Implementation Steps

1. Define an interface that declares a factory method.

2. Concrete classes implement this interface and override the factory method to produce the desired object.

3. The client code uses the factory method instead of calling the constructor directly.

6. Implementation in Go

// Import necessary packages
package main
import (
	"fmt"
)
// Step 1: Define the Product interface
type Product interface {
	Describe() string
}
// Step 2: Concrete products
type ConcreteProduct1 struct{}
func (p *ConcreteProduct1) Describe() string {
	return "This is ConcreteProduct1"
}
type ConcreteProduct2 struct{}
func (p *ConcreteProduct2) Describe() string {
	return "This is ConcreteProduct2"
}
// Step 3: Creator interface and concrete creators
type Creator interface {
	FactoryMethod() Product
}
type ConcreteCreator1 struct{}
func (c *ConcreteCreator1) FactoryMethod() Product {
	return &ConcreteProduct1{}
}
type ConcreteCreator2 struct{}
func (c *ConcreteCreator2) FactoryMethod() Product {
	return &ConcreteProduct2{}
}
// Client code
func DescribeProduct(c Creator) {
	product := c.FactoryMethod()
	fmt.Println(product.Describe())
}
func main() {
	creator1 := &ConcreteCreator1{}
	creator2 := &ConcreteCreator2{}
	DescribeProduct(creator1)
	DescribeProduct(creator2)
}

Output:

This is ConcreteProduct1
This is ConcreteProduct2

Explanation:

1. A Product interface is defined which represents the abstract product.

2. ConcreteProduct1 and ConcreteProduct2 are concrete implementations of the Product interface.

3. The Creator interface has a FactoryMethod which returns an object implementing the Product interface.

4. ConcreteCreator1 and ConcreteCreator2 are concrete creators implementing the Creator interface, providing their factory methods.

5. In the main function, two different creators are instantiated and their products are described using the DescribeProduct function.

7. When to use?

Use the Factory Method when:

1. A class can't anticipate the class of objects it is supposed to create.

2. Classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.

Remember that the Factory Method is about creating objects for which the exact type isn't known until runtime.


Comments