设计模式-----工厂模式(python版)

什么是工厂模式

工厂模式又称多态工厂模式和虚拟构造器模式,通过已经定义的工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。

大白话解释

您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。

代码实现

从上面说明来看可能还是不太清楚,下面我们用代码来一步一步的展现工厂模式。我们以写一个简单版的计算的代码来开始(只提供加减乘除的功能)

一般新手都会按照如下的方式进行开发

class Calculator(object):

    def operate(self, sn1, sn2, operate_type):
        """
        +-*/操作
        :param sn1: 数字1
        :param sn2: 数字2
        :param operate_type: 操作类型
        :return:
        """

        if not isinstance(sn1, int) or not not isinstance(sn1, float):
            raise Exception("sn1输入有误")
        if not isinstance(sn2, int) or not not isinstance(sn2, float):
            raise Exception("sn2输入有误")

        if operate_type == '+':
            return sn1 + sn2
        elif operate_type == '-':
            return sn1 - sn2
        elif operate_type == '*':
            return sn1 * sn2
        elif operate_type == '/':
            if sn2 != 0:
                return sn1 / sn2
            else:
                raise Exception("除数不能等于0")
        else:
            return "暂不支持此功能"


print(Calculator().operate(1, 2, "+"))

这种写法,将加减乘除运算全放在一个Calculator类中实现。虽然实现了计算器的功能,但增加其他功能的话就必须在operate方法中进行修改。这样的代码不易于我们后期的维护,扩展以及复用,并且耦合性高。

接下来我们就使用简单工厂模式来实现下上面的功能

class CalculatorFactory(object):

    def __init__(self, sn1, sn2):
        if not isinstance(sn1, int) or not not isinstance(sn1, float):
            raise Exception("sn1输入有误")
        if not isinstance(sn2, int) or not not isinstance(sn2, float):
            raise Exception("sn2输入有误")
        self.sn1 = sn1
        self.sn2 = sn2

    def calculation_result(self):
        pass


class Add(CalculatorFactory):
    """
    加法
    """

    def calculation_result(self):
        return self.sn1 + self.sn2


class Sub(CalculatorFactory):
    """
    减法
    """

    def calculation_result(self):
        return self.sn1 - self.sn2


class Mul(CalculatorFactory):
    """
    乘法
    """

    def calculation_result(self):
        return self.sn1 * self.sn2


class Division(CalculatorFactory):
    """
    除法
    """

    def calculation_result(self):
        if self.sn2 == 0:
            raise Exception("除数不能为0")
        return self.sn1 / self.sn2


class CreateCalculator(object):

    def calculator_operate(self, sn1, sn2, operate_type):
        if operate_type == '+':
            return Add(sn1, sn2)
        elif operate_type == '-':
            return Sub(sn1, sn2)
        elif operate_type == '*':
            return Mul(sn1, sn2)
        elif operate_type == '/':
            return Division(sn1, sn2)
        else:
            # 扩展类
            pass


简单工厂模式就是一个工厂对象根据不同参数创建不同的实例。工厂中包含了必要的逻辑,不需要考虑怎么实现。虽然相对于上一个版本已经有了一部分的优化,工厂模式的雏形已经显现出来,但是这个还是有一定的问题:工厂一旦需要生产新产品就需要修改工厂类的方法逻辑,违背了开放—封闭 原则(一个软件实体应当对扩展开放(open),则修改关闭(不修改原来的代码这就是closed))

接下来我们看下工厂模式

class CalculatorFactory(object):
    """
    抽象工厂类
    """

    def create_calculator(self):
        pass


class CalculatorAdd(CalculatorFactory):
    """
    具体工厂
    """

    def create_calculator(self):
        return Add()


class OperateProduct(object):
    """
    抽象产品类(+ - * / 等等)
    """

    def get_result(self, sn1, sn2):
        pass


class Add(OperateProduct):
    """
    具体产品
    """

    def get_result(self, sn1, sn2):
        return sn1 + sn2

从上面可以看出工厂模式的四要素:

  • 抽象产品类(Product):提供抽象方法供具体产品类实现
  • 具体产品类(ConcreteProduct):提供具体的产品
  • 抽象工厂类(Factory):提供抽象方法供具体工厂实现
  • 具体工厂类(ConcreteFactory):提供具体的工厂

我们一般也是这样使用的:

  1. 创建抽象工厂类,定义具体工厂的公共接口;
  2. 创建抽象产品类 ,定义具体产品的公共接口;
  3. 创建具体产品类(继承抽象产品类) ,定义生产的具体产品;
  4. 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
  5. 外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例

虽然我们通过工厂模式方便我们扩展以及复用,降低耦合性。但是看例子就可以看出来类太多了,所以一般如果要创建一系列复杂的对象,需要提供很多的创建信息;或者是我想要隐藏创建对象时候的“代码逻辑”,就需要使用工厂模式

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子林_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值