2. 工厂模式html
工厂模式是建立型设计模式的一种。核心的思想是,经过传递给类或函数某种产品的信息来建立产品并返回。当咱们想获得产品a对象,只需把产品a的名字传递给工厂函数就能获得产品a对象。而核心思想的背后是为了遵循著名的“开闭原则”:对扩展开放,对修改封闭。当添加新功能时,对已经有的函数代码不须要修改,只须要添加新功能相关的代码便可。python
举一个最简单的例子:假如咱们要写一个计算器,实现加减乘除四则运算,那么最简单的方法就是写一个函数,传入运算符,而后经过switch语句(python中没有switch语句,能够想办法用字典dict代替)。但问题也是显而易见的,若是咱们要添加一个新的运算,好比开平方,那么就要修改原来的包含了四则运算的函数,显然,在这个过程当中容易发生错误的修改,好比不当心改到了加法运算,这会让咱们原先写好的功能有被修改错误的风险。因此,对应到这个问题上,工厂模式的核心就是要把这几个运算给彻底独立出来,而且不影响运算主函数(即当添加新的运算时,咱们不须要修改运算主函数)。怎么作呢?其实就是建立一个工厂类,由这个工厂类经过判断传入的运算符,去对应实例化各个运算函数(或者运算类)。这样,当添加了新的运算时,咱们只须要添加新的运算函数(或者运算类),和修改工厂类(即添加新的switch判断,实例化新的运算函数或者运算类)就能够了。设计模式
2.1 简单工厂模式函数
简单工厂模式,是最简单的工厂方法模式,其由两部分组成,一是:工厂函数或工厂类,二是:产品类(能够是多个产品类A,B,C.........)。post
下面咱们经过一个简单的例子来看什么是简单工厂模式:url
class A(object): def __init__(self, product_type): self.product_type = product_type def __str__(self): return 'product %s' % self.product_type class B(object): def __init__(self, product_type): self.product_type = product_type def __str__(self): return 'product %s' % self.product_type class Factory(object): @staticmethod def yield_product(product_type): if product_type == 'A': return A(product_type) if product_type == 'B': return B(product_type) if __name__ == '__main__': a = Factory.yield_product('A') b = Factory.yield_product('B') print(a) print(b)
结果以下spa
product A
product B
上面代码中,实现了两个产品类A,B,一个工厂类Factory,工厂类中实现了一个静态方法,其实,能够用一个工厂函数来代替这个工厂类。静态方法能够经过类名进行调用,而不需把类实例化。.net
静态方法@staticmethod的意思是,这个方法是一个普通方法,虽然属于类,可是不用访问类的其余成员。而且能够在不把类实例化的前提下,经过类名进行调用。设计
2.2 工厂方法模式code
简单工厂模式存在一个问题,当要增长产品时,须要修改工厂类或者工厂方法,在上面的例子中,咱们须要修改工厂类的方法"yield_product"这违背了扩展开放,修改封闭的原则,所以是不可取的。工厂方法模式可以实现最小化地修改工厂类或工厂函数。
具体实现:对每个产品类再进行一次封装,封装成只生产特定产品的工厂类。
import abc class A(object): def __init__(self, product_type): self.product_type = product_type def __str__(self): return 'product %s' % self.product_type class B(object): def __init__(self, product_type): self.product_type = product_type def __str__(self): return 'product %s' % self.product_type class Abstract_factory(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def yield_product(self): pass class Factory_a(Abstract_factory): def yield_product(self): return A('A') class Factory_b(Abstract_factory): def yield_product(self): return B('B') def factory(product_type): if product_type == 'A': return Factory_a() if product_type == 'B': return Factory_b() if __name__ == '__main__': factory_a = factory('A') a = factory_a.yield_product() factory_b = factory('B') b = factory_b.yield_product() print(a) print(b)
结果以下
product A
product B
上述代码,Factory_a,Factory_b是对类A,B的封装,一个工厂只负责建立一个产品听从了单一职责原则,有利于代码的扩展和维护。
其中@abc.abstractmethod表示被该装饰器修饰的方法是一个抽象方法,没有实现,因此该基本不能被实例化。只有子类实现了该抽象方法才能被实例化。
参考连接:
1. python 设计模式(三) 工厂模式 https://blog.csdn.net/ruguowoshiyu/article/details/80657052
2. Python中的staticmethod与classmethod
3. python中@classmethod @staticmethod区别
4. Python2和Python3中@abstractmethod的用法 https://blog.csdn.net/xiemanR/article/details/72629164