【设计模式】工厂模式

前言

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",可以把这三个作为产品类,共同实现一个接口。
 

参考链接:

HEADFIRST设计模式

 Python 抽象工厂模式讲解和代码示例

一文详解“工厂方法模式”以及python语言的实现_python 工厂方法模式-CSDN博客

一文详解“工厂模式”以及python语言的实现-CSDN博客

相关推荐

  1. 设计模式工厂模式

    2024-01-08 23:14:01       46 阅读
  2. 设计模式--工厂模式

    2024-01-08 23:14:01       27 阅读
  3. 设计模式 工厂模式

    2024-01-08 23:14:01       26 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-08 23:14:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-08 23:14:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-08 23:14:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-08 23:14:01       20 阅读

热门阅读

  1. Spark基础二

    2024-01-08 23:14:01       30 阅读
  2. 自然语言处理中的语言模型

    2024-01-08 23:14:01       49 阅读
  3. 【Leetcode】242.有效的字母异位词

    2024-01-08 23:14:01       37 阅读
  4. 浅谈一些生命周期

    2024-01-08 23:14:01       41 阅读
  5. 预编译真的能完美防御SQL注入吗?

    2024-01-08 23:14:01       38 阅读
  6. 19.Linux Shell任务控制

    2024-01-08 23:14:01       36 阅读
  7. C++合并K个有序链表

    2024-01-08 23:14:01       29 阅读
  8. 一道经典的柯里化面试题

    2024-01-08 23:14:01       40 阅读