Design Patterns
Factory Pattern
Strategy Pattern
Software Development
Object-Oriented Programming

What is the difference between Factory and Strategy patterns?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

When developing software, design patterns are crucial for building systems that are scalable, efficient, and maintainable. Among the many design patterns, the "Factory" and "Strategy" patterns are widely used and often misunderstood. Both serve different purposes and solve different types of problems. Understanding their differences can greatly enhance the flexibility and robustness of your code.

The Factory Pattern

Overview

The Factory Pattern is a creational design pattern that provides an interface or abstract class for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. The core idea is to delegate the responsibility of object instantiation to subclasses.

Key Features

  • Object Creation: Mainly deals with the creation of objects.
  • Subtypes: Works well when dealing with a group of subclasses.
  • Flexibility: Increases code flexibility by avoiding tight coupling between the products and the client.
  • Focus: Best used when the exact types and dependencies of the objects to be created are pre-coded but the specific instantiation is deferred to the runtime.

Example

python
1# Example in Python
2from abc import ABC, abstractmethod
3
4class Product(ABC):
5    @abstractmethod
6    def operation(self) -> str:
7        pass
8
9class ConcreteProductA(Product):
10    def operation(self) -> str:
11        return "{Result of ConcreteProductA}"
12
13class ConcreteProductB(Product):
14    def operation(self) -> str:
15        return "{Result of ConcreteProductB}"
16
17class Creator(ABC):
18    @abstractmethod
19    def factory_method(self) -> Product:
20        pass
21
22    def some_operation(self) -> str:
23        product = self.factory_method()
24        result = f"Creator: The same creator's code has just worked with {product.operation()}"
25        return result
26
27class ConcreteCreatorA(Creator):
28    def factory_method(self) -> Product:
29        return ConcreteProductA()
30
31class ConcreteCreatorB(Creator):
32    def factory_method(self) -> Product:
33        return ConcreteProductB()
34
35def client_code(creator: Creator) -> None:
36    print(f"Client: {creator.some_operation()}")
37
38print("App: Launched with ConcreteCreatorA.")
39client_code(ConcreteCreatorA())
40
41print("App: Launched with ConcreteCreatorB.")
42client_code(ConcreteCreatorB())

The Strategy Pattern

Overview

The Strategy Pattern is a behavioral design pattern that enables selecting an algorithm's behavior at runtime. This pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It lets the algorithm vary independently from the clients that use it.

Key Features

  • Algorithm Selection: Focused on selecting and applying algorithms at runtime.
  • Encapsulation: Each algorithm is encapsulated and interchangeable.
  • Flexibility: Offers flexibility by enabling the client code to choose which algorithm to use without altering the algorithms themselves.
  • Focus: Best used when a program must handle different behaviors which are, for the most part, interchangeable.

Example

python
1# Example in Python
2from abc import ABC, abstractmethod
3
4class Strategy(ABC):
5    @abstractmethod
6    def do_algorithm(self, data: list) -> list:
7        pass
8
9class ConcreteStrategyA(Strategy):
10    def do_algorithm(self, data: list) -> list:
11        return sorted(data)
12
13class ConcreteStrategyB(Strategy):
14    def do_algorithm(self, data: list) -> list:
15        return list(reversed(sorted(data)))
16
17class Context:
18    def __init__(self, strategy: Strategy) -> None:
19        self._strategy = strategy
20
21    def set_strategy(self, strategy: Strategy) -> None:
22        self._strategy = strategy
23
24    def do_some_business_logic(self) -> None:
25        result = self._strategy.do_algorithm(["a", "b", "c", "d", "e"])
26        print(",".join(result))
27
28context = Context(ConcreteStrategyA())
29print("Client: Strategy is set to normal sorting.")
30context.do_some_business_logic()
31
32print("Client: Strategy is set to reverse sorting.")
33context.set_strategy(ConcreteStrategyB())
34context.do_some_business_logic()

Key Differences

AspectFactory PatternStrategy Pattern
CategoryCreationalBehavioral
PurposeManages and centralizes object creationEncapsulates algorithms and lets them vary independently
Main UseCreating instances of different classesChoosing algorithms at runtime
FocusOn creating objectsOn the behavior of algorithms
InterchangeabilityDifferent creations are interchangeableDifferent algorithms are interchangeable
FlexibilityEasy to add new types of productsEasy to switch between algorithms
Example of UseCar Factory creating different models like Sedan, SUVSort algorithms like QuickSort, MergeSort used in a context exchanging

By understanding these patterns and their differences, developers can effectively apply them when designing their systems, improving code maintenance, and promoting reusable components. The Factory pattern streamlines object creation, while the Strategy pattern facilitates algorithm interchangeability, making both indispensable tools in software engineering.


Course illustration
Course illustration

All Rights Reserved.