Python: Fruits and Design Patterns-Factory Pattern

Factory Pattern: Belongs to the creation mode, which provides the best way to create objects. In the factory model, weWhen creating an object, the creation logic is not exposed to the client, and it uses a common interface to point to the newly created object .

intention: 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

Main solution: Mainly solve the problem of interface selection.

When to use: We clearly plan to create different instances under different conditions.

How to solve: Let its subclasses implement the factory interface.

Key code: The creation process is executed in its subclasses.

advantage: 1. A caller wants to create an object, as long as he knows its name. 2. High scalability. If you want to add a product, you only need to extend a factory class. 3. Shield the specific implementation of the product, and the caller only cares about the interface of the product.

Disadvantage: Every time you add a product, you need to add a concrete class and object implementation factory, which doubles the number of classes in the system, which increases the complexity of the system to a certain extent, and at the same time increases the dependency on the specific classes of the system . This is not a good thing.

Precautions: As a type of creation pattern, wherever complex objects need to be generated, the factory method pattern can be used. One thing to note is that complex objects are suitable for using the factory pattern, while simple objects, especially objects that only need to be created through new, do not need to use the factory pattern. If you use the factory pattern, you need to introduce a factory class, which will increase the complexity of the system.

Applications:我想买一些水果(橘子、哈密瓜和葡萄),我可以直接从水果工厂里面购买,但是我不需要知道这些水果的产地是哪里的,它们是如何运输和包装的,以及水果工厂的相关流水线是如何运作的。

Insert picture description here

Then let's take a look at how to use the factory model to realize a small project to buy different fruits? (づ。◕ᴗᴗ◕。)づ

Idea of ​​realization:

  • The main body of the project consists of 3 parts:消费者(买水果的人),水果工厂(卖水果的人),水果大类(实现隐藏的工厂内部细节)
  • 消费者主要向水果工厂传达“购买需求”的相关信息(水果的种类、包装、重量等...);
  • 水果工厂主要针对消费者的不同“购买需求”将调用不同的水果大类中的子类方法;
  • 水果大类主要划分为各种小类,针对每一类水果有独特的设计实现细节。

The UML use case diagram of the project is as follows:

Insert picture description here

The implemented code is as follows:

class Fruit:
    # 水果大类
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight
        self.price = None
	
    # 计算购买金额的抽象接口
    def purchase(self):
        pass
	# 展示购买信息的抽象接口
    def show(self):
        pass


class Orange(Fruit):
    # 橘子类
    def __init__(self, name, weight, variety):
        Fruit.__init__(self, name, weight)
        # 不同的橘子类型,价格不同
        if variety == 1:
            self.price = 8.5
        else:
            self.price = 11.0
        # 设定购买的橘子的类型
        self.variety = variety

    def purchase(self):
        money = self.price * self.weight
        return money

    def show(self):
        money = self.purchase()
        print("您购买的水果:%s,单价为:%s(千克/元),重量为:%f千克\n需要支付的金额共计为:%f元" %
              (self.name, self.price, self.weight, money))


class Hami_Melon(Fruit):
    # 哈密瓜类
    def __init__(self, name, weight):
        Fruit.__init__(self, name, weight)
        # 设定哈密瓜的单价
        self.price = 24.3

    def purchase(self):
        money = self.price * self.weight
        return money

    def show(self):
        money = self.purchase()
        print("您购买的水果:%s,单价为:%s(千克/元),重量为:%f千克\n需要支付的金额共计为:%f元" %
              (self.name, self.price, self.weight, money))


class Grape(Fruit):
    # 葡萄类
    def __init__(self, name, weight, pack):
        Fruit.__init__(self, name, weight)
        # 设定葡萄的单价
        self.price = 16.2
        # 设定葡萄的包装方式
        self.pack = pack

    def purchase(self):
        money = self.price * self.weight
        return money

    def show(self):
        money = self.purchase()
        print("您购买的水果:%s,单价为:%s(千克/元),重量为:%f千克\n需要支付的金额共计为:%f元" %
              (self.name, self.price, self.weight, money))


class FruitFactory:
    # 水果工厂类
    def get_info(self, name, weight, variety, pack):
        weight = float(weight)
        variety, pack = int(variety), int(pack)
        if variety == 0 and pack == 0:
            new_object = Hami_Melon(name, weight)
            return new_object
        elif variety > 0 and pack == 0:
            new_object = Orange(name, weight, variety)
            return new_object
        elif variety == 0 and pack > 0:
            new_object = Orange(name, weight, pack)
            return new_object
        else:
            return None


class Consumer:
    # 消费者类
    def __init__(self):
        # 输入原始的“购买需求”信息
        self.name = input("请输入你要购买的水果名称:orange / hami_Melon / grape\n")
        self.weight = input("请输入你要购买水果的重量(kg):\n")
        self.variety = input("如果您购买橘子,我们有2种橘子:0.不买橘子 1.甘橘 2.砂糖橘\n")
        self.pack = input("如果您购买葡萄,有2中包装方式:0.不买葡萄 1.散称 2.盒装\n")

    def request(self):
        # 返回相关的购买信息
        return self.name, self.weight, self.variety, self.pack


if __name__ == '__main__':
    # 创建顾客
    buyer = Consumer()
    # 拿到顾客的购买信息
    buy_info = buyer.request()
    # 使用水果工厂,传达指令至水果大类并执行购买操作
    buy_res = FruitFactory().get_info(buy_info[0], buy_info[1], buy_info[2], buy_info[3])
    # 购买信息的展示
    buy_res.show()

Related test cases:

Insert picture description here
Insert picture description here
Insert picture description here

For the explanation of design patterns in this article , please refer to the link: Abstract Factory Pattern.
If you have a small partner who is not familiar with the creation and inheritance of python classes, please refer to this blog: Inheritance of python classes