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.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
#=================================
#定义创建对象的一个工厂
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 None
if __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.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}')
也有缺点
在增加新的一个类型时,也必须增加相应的新的工厂类,会带来额外的开销,会导致很多的工厂类,影响代码的简洁性。
?1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
?
参考链接: