SoFunction
Updated on 2024-11-13

Python design patterns of the abstract factory pattern explains

Abstract Factory Pattern (Abstract Factory Pattern): belongs to the creation pattern, which provides an optimal way to create objects. In the Abstract Factory Pattern, interfaces are factories responsible for creating a relevant object without explicitly specifying their class, and each generated factory can provide objects according to the factory pattern.

Intent: To provide an interface for creating a set of related or interdependent objects without specifying their specific classes.

Primary solution: Primary solution for interface selection.

When to use: The system has more than one product family, and the system consumes products from only one of those families.

How to solve: Define multiple products inside a product family.

KEY CODE: Aggregate multiple similar products in a single plant.

Advantages: When multiple objects in a product family are designed to work together, it ensures that the client always uses only objects from the same product family. Abstract factory pattern compared to the factory pattern, the division is more explicit and clear, in the face of complex production tasks, management and production performance will be more efficient.

Disadvantages: It is very difficult to expand the product family by adding a whole series of a particular product.

Caveat: Product families are hard to scale, product levels are easy to scale.

Application Example: For a factory producing fruits, the factory pattern mainly creates a factory for one kind of fruits covering all the business related to the fruits (e.g., the transportation, preservation, processing, packaging, selling and other related business of grapes are all contracted by the factory); while the abstract factory pattern mainly creates the corresponding factories for a certain part of the production (e.g., the transportation factory is responsible for managing the transportation of all fruits, the selling factory is responsible for managing the price and selling of all fruits, the inventory factory is responsible for managing the inventory count of all fruits, etc.). (e.g. transportation factory is responsible for managing the transportation of all fruits, selling factory is responsible for managing the price and selling of all fruits, inventory factory is responsible for managing the inventory count of all fruits, etc.).

在这里插入图片描述


So let's build a small project to buy fruits at the cash register using the abstract factory pattern! (づ◕ᴗ◕◕◕◕◕◕◕) づ

Ideas for realization

The main body of the project consists of 6 parts: the consumer (the person who buys the fruit), the fruit factory (the person who sells the fruit), and the sub-factories of the fruit factory (variety factory, price factory, packaging factory, weighing factory). ...); Fruit Factory mainly assigns tasks to sub-factories to fulfill different "purchase demands" of consumers; Variety Factory is responsible for managing the variety of fruits, Price Factory is responsible for managing the price of fruits, Weighing Factory is responsible for weighing fruits, and Packing Factory is responsible for the way of packing fruits.

The UML use case diagram for the project is shown below:

在这里插入图片描述

The implemented code is as follows:

class FruitClass:
    # Variety plant
    def get_name(self, name_index):
        if name_index == 0:
            name_object = OrangeClass()
        elif name_index == 1:
            name_object = Hami_MelonClass()
        elif name_index == 2:
            name_object = GrapeClass()
        else:
            name_object = None

        return name_object


class OrangeClass:
    # Orange
    def __init__(self):
         = "Oranges."

    def print_name(self):
        print("The fruit you purchased is: %s" % )


class Hami_MelonClass:
    # Cantaloupe
    def __init__(self):
         = "Cantaloupe."

    def print_name(self):
        print("The fruit you purchased is: %s" % )


class GrapeClass:
    # Grapes
    def __init__(self):
         = "Grapes."

    def print_name(self):
        print("The fruit you purchased is: %s" % )


class FruitWeight:
    # Weighing plants
    def __init__(self, weight):
         = float(weight)

    def print_weight(self):
        print("The weight of the fruit is: %.2f kilograms" % )


class FruitPrice:
    # Price factory
    def get_price(self, name_index, variety):
        if name_index == 0:
            price_object = OrangePrice(variety)
        elif name_index == 1:
            price_object = Hami_MelonPrice()
        elif name_index == 2:
            price_object = GrapePrice()
        else:
            price_object = None

        return price_object


class OrangePrice:
    # Orange price category
    def __init__(self, variety):
         = variety
        if  == 1:
             = 8.5
        else:
             = 11.0

    def print_price(self):
        print("The unit price of this fruit is :%.2f$/kg" % )


class Hami_MelonPrice:
    # Cantaloupe price category
    def __init__(self):
         = 24.3

    def print_price(self):
        print("The price of this fruit is :%.2f$/kg" % )


class GrapePrice:
    # Grape price category
    def __init__(self):
         = 16.2

    def print_price(self):
        print("The price of this fruit is :%.2f$/kg" % )
        return 


class FruitPack:
    # Packaging plants
    def __init__(self, pack):
        if pack == 1:
             = "Loosely referred to as"
        else:
             = "Boxed."

    def print_pack(self):
        print("The fruit is packed in %s" % )


class FruitFactory:
    def __init__(self, name_index, weight, variety, pack):
        # Assignment of tasks, variety, weight, price, packing method
        self.name_object = FruitClass().get_name(name_index)
        self.weight_object = FruitWeight(weight)
        self.price_object = FruitPrice().get_price(name_index, variety)
        self.pack_object = FruitPack(pack)

    def print_purchase(self):
        # Calculate the amount purchased
        money = self.price_object.price * self.weight_object.weight
        print("The total amount to be paid is: %.2f dollars" % money)

    def show_info(self):
        # Demonstrate final purchase information
        self.name_object.print_name()
        self.weight_object.print_weight()
        self.price_object.print_price()
        self.pack_object.print_pack()
        self.print_purchase()
        print("-*-" * 20)


class Consumer:
    # Consumer class
    def __init__(self):
        print("-*-" * 20)
        # Enter the original "need to buy" information
         = input("Please enter the name of the fruit you want to buy: 0. orange 1. cantaloupe 2. grapes \n")
         = input("Please enter the weight of the fruit you want to buy(kg):\n")
         = input("If you buy oranges, we have 2 kinds of oranges: 0. No oranges 1. Sweet oranges 2. Sugar oranges\n")
         = input("Please choose how you would like this fruit to be packaged: 1. in bulk 2. in boxes\n")
        print("-*-" * 20)

    def request(self):
        # Return relevant purchase information
        return , , , 


if __name__ == '__main__':
    # Create customers
    buyer = Consumer()
    # Get the customer's purchase information
    buy_info = ()
    # Use fruit factories to communicate orders to their sub-factories and perform purchasing operations
    buy_res = FruitFactory(int(buy_info[0]), int(buy_info[1]), int(buy_info[2]), int(buy_info[3]))
    # Display of purchase information
    buy_res.show_info()

related test cases:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

This article on design patterns explains the idea, refer to the link:Abstract Factory Pattern
If any of you are not familiar with the usage of python class creation and inheritance etc, please refer to this blog: Inheritance of python classes

to this article on the python design pattern of the abstract factory pattern is introduced to this article, more related python abstract factory pattern content please search my previous articles or continue to browse the following related articles I hope you will support me in the future more!