Перейти к содержанию

Factory Method

Also known as "Virtual Constructor". This pattern defines a common interface for creating objects in a superclass, allowing subclasses to change the type of objects being created.

Note

The pattern is applicable when the program has a hierarchy of product classes.

Pattern structure

The participants classes in this pattern are:

  1. Product defines the interface for objects the factory method creates.
  2. ConcreteProduct implements the Product interface.
  3. Creator(also referred as Factory because it creates the Product objects) declares the method factory_method, which returns a Product object. May call the generating method for creating Product objects ConcreteCreator overrides the generating method for creating ConcreteProduct objects.
---
title: Factory Method
---

classDiagram
    direction TD


    %% Defining relationships between classes
    Creator <|-- ConcreteCreatorA
    Creator <|-- ConcreteCreatorB

    Product <|.. ConcreteProductA
    Product <|.. ConcreteProductB

    Creator ..> Product


    %% Notes
    note for Creator """def some_operation(self):
        product = self.factory_method()
        result = product.do_something()
        return result
    """
    note for ConcreteCreatorA "return ConcreteProductA()"
    note for ConcreteCreatorB "return ConcreteProductB()"


    %% Defining classes
    class Creator{
        ...
        +some_operation()
        +factory_method()* Product
    }

    class ConcreteCreatorA{
        ...
        +factory_method() Product
    }
    class ConcreteCreatorB{
        ...
        +factory_method() Product
    }


    class Product{
        <<interface>>
        ...
        +do_something()*
    }

    class ConcreteProductA{
    ...
    +do_something()
    }

    class ConcreteProductB{
    ...
    +do_something()
    }

Sample code in Python

factory_method.py
from abc import ABC, abstractmethod


class Creator(ABC):

    @abstractmethod
    def factory_method(self):
        pass

    def some_operation(self) -> str:
        # Call the factory method to create a Product object.
        product = self.factory_method()

        # Now, use the product.
        return product.do_something()


class ConcreteCreatorA(Creator):

    def factory_method(self) -> Product:
        return ConcreteProductA()


class ConcreteCreatorB(Creator):

    def factory_method(self) -> Product:
        return ConcreteProductB()



class Product(ABC):

    @abstractmethod
    def do_something(self) -> str:
        pass


class ConcreteProductA(Product):

    def do_something(self) -> str:
        return 'Result of the ConcreteProductA'


class ConcreteProductB(Product):

    def do_something(self) -> str:
        return 'Result of the ConcreteProductB'


def client_code(creator: Creator) -> None:
    creator.some_operation()


if __name__ == '__main__':
    print('App: Launched with the ConcreteCreatorA.')
    client_code(ConcreteCreatorA())

    print('\n')

    print('App: Launched with the ConcreteCreatorB.')
    client_code(ConcreteCreatorB())