【设计模式】工厂模式
前言
1. 单例模式(Singleton Pattern):保证一个类只有一个实例,并提供一个全局的访问点。
2. 工厂模式(Factory Pattern):定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。
3. 观察者模式(Observer Pattern):定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会被自动通知并更新。
4. 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,而不会影响到其他对象。
5. 策略模式(Strategy Pattern):定义一系列的算法,将每个算法封装起来,并使它们可以相互替换。
6. 命令模式(Command Pattern):将请求封装成一个对象,从而使用户可以用不同的请求对客户进行参数化。
7. 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的类能够一起工作。
8. 外观模式(Facade Pattern):为子系统中的一组接口提供一个统一的接口,从而使得子系统更加容易使用。
9. 状态模式(State Pattern):允许一个对象在其内部状态改变时改变其行为。
10. 模板方法模式(Template Method Pattern):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中实现。
这些是Python中常用的设计模式,通过使用这些设计模式可以提高代码的可读性、可维护性和重用性。
工厂模式(Factory Pattern)是 程序设计中 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式 中,我们在创建对象时不会对客户端暴露创建逻辑,所谓的“创建逻辑”是指我必须要知道创建函数的构造函数的逻辑组成,才能创建对象。
简单工厂模式
隐藏创建类的代码逻辑
import math#定义4个图形类,并且每一个图形都有一个可以计算面积的方法
class Circle:def Area(self,radius):return math.pow(radius,2)*math.piclass Rectangle:def Area(self,longth,width):return 2*longth*widthclass Triangle:def Area(self,baselong,height):return baselong*height/2class Ellipse:def Area(self,long_a,short_b):return long_a*short_b*math.pi#=================================
#定义创建对象的一个工厂
class Factory:def create_shape(self, name):if name =='Circle':return Circle()elif name == 'Rectangle':return Rectangle()elif name == 'Triangle':return Triangle()elif name == 'Ellipse':return Ellipse()else:return Noneif __name__=='__main__':factory=Factory()circle=factory.create_shape('Circle')circle_area=circle.Area(2)print(f'这是一个圆,它的面积是:{circle_area}')rectangle=factory.create_shape('Rectangle')rectangle_area=rectangle.Area(2,3)print(f'这是一个长方形,它的面积是:{rectangle_area}')triangle=factory.create_shape('Triangle')triangle_area=triangle.Area(2,3)print(f'这是一个三角形,它的面积是:{triangle_area}')ellipse=factory.create_shape('Ellipse')ellipse_area=ellipse.Area(3,2)print(f'这是一个椭圆,它的面积是:{ellipse_area}')
问题所在:不符合软件设计的开放-封闭原则,对扩展开放对修改关闭。扩展一个类的创建时,需要修改Factory类,增加if-else代码。
解决方法:定义一个创建工厂的接口(python中通过类的继承来实现),将所有的类创建的实现单独拎出来并继承抽象工厂类(接口),实现抽象类中的创建类的方法,不放在一起。这样有新的类需要扩展时,就可以直接创建一个新的工厂类,里面实现实例化逻辑,不必修改原有的代码,最后是增加具体类并实现该类的一些行为方法
工厂模式
import math#定义4个图形类,并且每一个图形都有一个可以计算面积的方法
class Circle:def Area(self,radius):return math.pow(radius,2)*math.piclass Rectangle:def Area(self,longth,width):return 2*longth*widthclass Triangle:def Area(self,baselong,height):return baselong*height/2class Ellipse:def Area(self,long_a,short_b):return long_a*short_b*math.pi#=================================
#定义创建对象的工厂接口,因为python中并没有接口的概念,所以,这里打算通过“类的继承”加以实现
class IFactory: #模拟接口def create_shape(self): #定义接口的方法,只提供方法的声明,不提供方法的具体实现passclass 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}')
也有缺点
在增加新的一个类型时,也必须增加相应的新的工厂类,会带来额外的开销,会导致很多的工厂类,影响代码的简洁性。
应用场景
1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
参考链接:
HEADFIRST设计模式
Python 抽象工厂模式讲解和代码示例
一文详解“工厂方法模式”以及python语言的实现_python 工厂方法模式-CSDN博客
一文详解“工厂模式”以及python语言的实现-CSDN博客