Sobes.tech
Middle+
208

What is an abstract factory?

Answer from AI

sobes.tech AI

Abstract Factory is a creational pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes.

Main components:

  • Abstract Factory: An interface declaring a set of methods for creating abstract products.
  • Concrete Factory: Implements the abstract factory to create concrete objects of a family.
  • Abstract Product: An interface for a type of object created by the corresponding factory method.
  • Concrete Product: Implements the abstract product interface, created by a specific concrete factory.
  • Client: The code that uses the interfaces of the abstract factory and products. The client is independent of the concrete classes of factories or products.

Advantages:

  • Isolates the client from concrete product classes.
  • Ensures consistency among products of the same family.
  • Simplifies replacing product families.

Disadvantages:

  • Adding a new product type may require changes across all factories.

Example structure:

// Abstract Factory
class AbstractFactory:
    def create_product_a(self):
        pass

    def create_product_b(self):
        pass

// Concrete Factory 1
class ConcreteFactory1(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductA1()

    def create_product_b(self):
        return ConcreteProductB1()

// Concrete Factory 2
class ConcreteFactory2(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductA2()

    def create_product_b(self):
        return ConcreteProductB2()

// Abstract Product A
class AbstractProductA:
    def useful_function_a(self):
        pass

// Concrete Product A1
class ConcreteProductA1(AbstractProductA):
    def useful_function_a(self):
        return "The result of the product A1."

// Concrete Product A2
class ConcreteProductA2(AbstractProductA):
    def useful_function_a(self):
        return "The result of the product A2."

// Abstract Product B
class AbstractProductB:
    def useful_function_b(self):
        pass

    def another_useful_function_b(self, collaborator):
        pass

// Concrete Product B1
class ConcreteProductB1(AbstractProductB):
    def useful_function_b(self):
        return "The result of the product B1."

    def another_useful_function_b(self, collaborator):
        # B1 works with A1
        result = collaborator.useful_function_a()
        return f"The result of the B1 collaborating with the ({result})"

// Concrete Product B2
class ConcreteProductB2(AbstractProductB):
    def useful_function_b(self):
        return "The result of the product B2."

    def another_useful_function_b(self, collaborator):
        # B2 works with A2
        result = collaborator.useful_function_a()
        return f"The result of the B2 collaborating with the ({result})"

// Client code
def client_code(factory: AbstractFactory):
    product_a = factory.create_product_a()
    product_b = factory.create_product_b()

    print(f"{product_b.useful_function_b()}")
    print(f"{product_b.another_useful_function_b(product_a)}")

# Usage example
if __name__ == "__main__":
    print("Client: Testing client code with the first factory type:")
    client_code(ConcreteFactory1())

    print("\nClient: Testing the same client code with the second factory type:")
    client_code(ConcreteFactory2())