chatGPT生成的简单工厂模式代码教学

发布时间 2023-04-25 15:20:59作者: (ToT)
"""
在这个示例代码中,我们使用了简单工厂模式来创建不同的运算对象。首先,我们定义了一个 Operation 类作为运算类的基类,其中包含两个操作数 num1 和 num2,
以及一个 get_result 方法用于获取运算结果。

接下来,我们定义了四个具体的运算子类 Add、Subtract、Multiply 和 Divide,分别实现了加法、减法、乘法和除法的计算方法。这些子类都继承自 Operation
基类,并重载了 get_result 方法实现自己的运算逻辑。

最后,我们使用一个简单工厂类 OperationFactory 来创建不同的运算对象。这个工厂类包含一个静态方法 create_operation,根据传入的参数来判断应该创建
哪种类型的运算对象,并返回相应的对象实例。

在 main 函数中,我们首先读取两个输入数值和一个运算符号,然后调用 OperationFactory 类的 create_operation 方法来创建对应的运算对象。最后,我们
调用该对象的 get_result 方法获取运算结果,并将结果输出到屏幕上。

使用简单工厂模式封装可以使代码结构更加清晰,便于后期的扩展和维护。如果需要添加其他的运算方法,只需要创建相应的子类,并在工厂类中添加对应的判断逻辑即可。
UML类图
+---------------+                               +------------------+
|   Operation   |                               |  OperationFactory|
+---------------+                               +------------------+
|  - num1: float |                               +------------------+
|  - num2: float |                               | + create_operation(num1: float, num2: float, operator: str): Operation |
+---------------+                               +------------------+
| + get_result():|                                            |
+---------------+                                            |
             ^                                              |
             |                                              |
         +-------+                                     +-----------+
         | Add   |                                     |  Subtract |
         +-------+                                     +-----------+
         |       |                                     |           |
         +-------+                                     +-----------+
              ^                                               ^
              |                                               |
         +-------+                                     +-----------+
         |Multiply|                                     |  Divide   |
         +-------+                                     +-----------+

在上面的UML类图中,我们可以看到类之间的关系。其中 Operation 类作为运算基类,包含了两个操作数 num1 和 num2,以及一个抽象方法 get_result。它作
为其他子类的父类,并提供了一个统一的接口。

Add、Subtract、Multiply 和 Divide 类分别实现了加法、减法、乘法和除法,它们继承了 Operation 基类,并实现了自己的 get_result 方法。在这些子
类中,我们可以看到它们所继承的属性和方法。

最后,OperationFactory 是一个简单工厂类,用于创建不同的运算对象。它提供了一个静态方法 create_operation,根据传入的参数来判断应该创建哪种类型的
运算对象,并返回相应的对象实例。

通过这个UML类图,我们可以更清晰地了解这个程序的结构和类之间的关系,方便进行后续的扩展和维护。

"""


class Operation:
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2

    def get_result(self):
        pass


class Add(Operation):
    def get_result(self):
        return self.num1 + self.num2


"""
在这个程序中,Add 是一个类,它继承自父类 Operation。继承后,Add 类拥有了父类的属性和方法,并且可以在此基础上添加自己独有的属性和方法。

Add 类中并没有定义参数,但是它会继承父类 Operation 的构造函数,即 __init__ 方法。所以当创建一个 Add 对象时,需要传入两个参数 num1 和 num2,
以供初始化父类属性。这两个参数会被传递给 Operation 父类的 __init__ 方法,完成对象的初始化。

get_result 方法是用来计算数学运算结果的方法,在 Add 类中其具体实现为将两个数相加并返回结果。由于 Add 类继承自 Operation 父类,因此实例化一个 
Add 对象并调用 get_result 方法,就可以得到计算出来的结果了。
"""


class Subtract(Operation):
    def get_result(self):
        return self.num1 - self.num2


class Multiply(Operation):
    def get_result(self):
        return self.num1 * self.num2


class Divide(Operation):
    def get_result(self):
        if self.num2 == 0:
            raise ZeroDivisionError("除数不能为0")
        return self.num1 / self.num2


"""
Python 中常见的 raise 异常类型包括但不限于以下几种:

- AttributeError:     当访问一个对象属性或方法不存在时抛出;
- ValueError:         当传递给函数的参数不合法时抛出;
- TypeError:          当传递给函数的参数类型不正确时抛出;
- NameError:          当访问一个未定义的变量时抛出;
- KeyError:           当使用字典中不存在的键时抛出;
- IndexError:         当使用列表中不存在的索引时抛出;
- ZeroDivisionError:  当用 0 作为除数时抛出;
- FileNotFoundError:  当文件不存在时抛出;
- OSError:            当系统操作产生错误时抛出。

需要注意的是,在 Python 中,程序员可以自定义异常类型,并通过 raise 语句手动抛出。通过自定义异常类型,可以更准确地描述错误信息,以便程序能够更好地处
理和调试问题。
"""


class OperationFactory:
    @staticmethod
    def create_operation(num1, num2, operator):
        if operator == '+':
            return Add(num1, num2)
        elif operator == '-':
            return Subtract(num1, num2)
        elif operator == '*':
            return Multiply(num1, num2)
        elif operator == '/':
            return Divide(num1, num2)


"""
@staticmethod 是 Python 语言中的一个装饰器,用于将方法定义为静态方法。在定义静态方法时需要使用该装饰器来修饰。

静态方法是指与类的实例无关的方法,在调用时不会隐式地传入实例参数 self,而是可以直接使用类名进行调用。同时,由于静态方法不需要访问实例属性和方法,因此
它们通常用于进行一些类相关但是又不需要使用实例属性和方法的操作,比如工厂模式中的对象创建方法或者是工具类函数等。

在本程序中,create_operation 方法是一个静态方法,用于根据传入的参数创建不同类型的运算对象。由于这个方法只涉及到类级别的操作,并不需要使用实例变量,
因此将其定义为静态方法可以使得代码更加简洁,便于使用类名进行调用。
"""


def main():
    num1 = float(input("请输入第一个数:"))
    num2 = float(input("请输入第二个数:"))
    operator = input("请输入运算符号:")

    operation = OperationFactory.create_operation(num1, num2, operator)
    result = operation.get_result()

    print("计算结果为:", result)


if __name__ == '__main__':
    main()

"""
这个 __name__ 属性是 Python 自带的一个内置属性,用来表示当前模块的名称。当一个 Python 文件被直接运行时,这个属性的值就是 '__main__'。所以在脚
本文件中,可以通过判断 __name__ 的值是否为 '__main__' 来区分模块是被导入还是直接运行。

具体来说,如果我们在一个单独的 Python 文件中定义了一些函数或类,并把它们放在了 if __name__ == '__main__': 语句块中,那么当我们运行这个 Python 
文件时,这些函数和类只会在这个文件作为主程序被运行时才执行。而如果我们把这个文件作为一个模块导入到其他 Python 文件中,这些函数和类就不会被执行。
"""