一、什么是“工厂方法模式”——Factory_Method Pattern
概念解析:有的设计模式资料里面,可能将“工厂方法模式”与上所讲的“简单工厂模式”混为一谈,或者是将两者的概念合并,本文还是将二者分开处理的。
工厂方法模式 是对简单工厂模式的一个延伸,所以它们诞生的背景以及所解决的问题是大同小异的,本文就不再额外交代,不清楚的可以查阅另一片设计模式的文章。这样说是因为简单工厂违反了开放——封闭的原则,而此时工厂方法却可以完美的解决这个问题!那它到底是怎么解决的呢?
我们知道,工厂模式,只提供了一个工厂类,这个工厂类重定义一个创建类型的函数去创建每一种类型,如下所示:
但是“工厂方法模式”则是提供了一系列的工厂创建类,即每一种类型对应于一种工厂,但是这些工厂又遵循一个工厂接口,只不过是重新实现了接口中的创建方法,如下图所示:
二、工厂方法模式的Python代码实现
import math
#定义4个图形类,并且每一个图形都有一个可以计算面积的方法
class Circle:
def Area(self,radius):
return math.pow(radius,2)*math.pi
class Rectangle:
def Area(self,longth,width):
return 2*longth*width
class Triangle:
def Area(self,baselong,height):
return baselong*height/2
class Ellipse:
def Area(self,long_a,short_b):
return long_a*short_b*math.pi
#=================================
#定义创建对象的工厂接口,因为python中并没有接口的概念,所以,这里打算通过“类的继承”加以实现
class IFactory: #模拟接口
def create_shape(self): #定义接口的方法,只提供方法的声明,不提供方法的具体实现
pass
class CircleFactory(IFactory): #模拟类型实现某一个接口,实际上是类的继承
def create_shape(self, name): #重写接口中的方法
if name =='Circle':
return Circle()
class RectangleFactory(IFactory): #模拟类型实现某一个接口,实际上是类的继承
def create_shape(self, name): #重写接口中的方法
if name =='Rectangle':
return Rectangle()
class TriangleFactory(IFactory): #模拟类型实现某一个接口,实际上是类的继承
def create_shape(self, name): #重写接口中的方法
if name =='Triangle':
return Triangle()
class EllipseFactory(IFactory): #模拟类型实现某一个接口,实际上是类的继承
def create_shape(self, name): #重写接口中的方法
if name =='Ellipse':
return Ellipse()
if __name__=='__main__':
factory1=CircleFactory()
factory2=RectangleFactory()
factory3=TriangleFactory()
factory4=EllipseFactory()
circle=factory1.create_shape('Circle')
circle_area=circle.Area(2)
print(f'这是一个圆,它的面积是:{circle_area}')
rectangle=factory2.create_shape('Rectangle')
rectangle_area=rectangle.Area(2,3)
print(f'这是一个长方形,它的面积是:{rectangle_area}')
triangle=factory3.create_shape('Triangle')
triangle_area=triangle.Area(2,3)
print(f'这是一个三角形,它的面积是:{triangle_area}')
ellipse=factory4.create_shape('Ellipse')
ellipse_area=ellipse.Area(3,2)
print(f'这是一个椭圆,它的面积是:{ellipse_area}')
上面的运行结果如下:
这是一个圆,它的面积是:12.566370614359172
这是一个长方形,它的面积是:12
这是一个三角形,它的面积是:3.0
这是一个椭圆,它的面积是:18.84955592153876
三、工厂方法函数的优缺点总结
优点:
(1)工厂方法模式具有简单工厂模式的优点,那就是用户不需要知道创建某一个类型的细节,即隐藏了代码的“创建逻辑”
(2)在增加一个新的图形类的时候,比如再加一个平行四边形,我不用去修改代码,只需要增加对应的平行四边形工厂就好,完全符合开放——封闭性原则! 自己添加一个平行四边形工厂类,只要让其实现抽象的工厂接口就可以啦,即只需要自己编写拓展模块,而不用更改原来的代码。这完美的体现了多态性!
缺点:
(1)在增加新的一个类型时,也必须增加相应的新的工厂类,会带来额外的开销,会导致很多的工厂类,影响代码的简洁性。