Bootstrap

设计模式Python版 简单工厂模式


前言

GOF设计模式分三大类:

  • 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
  • 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
  • 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

一、简单工厂模式

简单工厂模式(Simple Factory Pattern)

  • 定义:定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。。

  • 解决问题:如何将对象的创建和对象的使用分离?

  • 使用场景:

    • 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
    • 当类创建的对象需要根据运行时的条件来决定时,如根据配置文件
  • 组成:

    • 工厂(Factory):负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
    • 抽象产品(Product):是简单工厂创建的所有对象的父类或接口,负责描述所有实例共有的公共接口。
    • 具体产品(Concrete Product):实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建。
  • 优点:

    • 隔离变化,把变化部分抽象独立出来。
    • 将对象的创建和使用分离,也使得系统更加符合单一职责原则,有利于对功能的复用和系统的维护。
  • 缺点:

    • 工厂类集中了所有产品的创建逻辑,职责过重
    • 采用简单工厂模式时,当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码,将违背开闭原则。

在这里插入图片描述

二、简单工厂模式示例

客户端代码通过调用Chart类的构造函数来创建图表对象,根据参数type的不同可以得到不同类型的图表,然后再调用display()方法来显示相应的图表。

  • 重构前代码:Chart类中包含很多“if…else…”代码块。Chart类的职责过重,它负责初始化和显示所有的图表对象。当需要增加新类型的图表时,必须修改Chart类的源代码,违反了开闭原则。
class Chat:
    def __init__(self, type: str):
        self.type = type
        if type == "histogram":
            print("初始化柱状图")
        elif type == "pie":
            print("初始化饼状图")
        elif type == "line":
            print("初始化折线图")

    def display(self):
        if self.type == "histogram":
            print("显示柱状图")
        elif self.type == "pie":
            print("显示饼状图")
        elif self.type == "line":
            print("显示折线图")

# 客户端测试代码
chat = Chat("pie")
chat.display()


### 输出结果
初始化饼状图
显示饼状图
  • 重构后代码:使用简单工厂模式重构代码
class Chat:
    """抽象产品"""

    def display(self):
        raise NotImplementedError


class HistogramChart(Chat):
    """具体产品"""

    def __init__(self):
        print("创建柱状图")

    def display(self):
        print("显示柱状图")


class PieChart(Chat):
    def __init__(self):
        print("创建饼状图")

    def display(self):
        print("显示饼状图")


class LineChart(Chat):
    def __init__(self):
        print("创建折线图")

    def display(self):
        print("显示折线图")


class ChartFactory:
    """工厂"""

    @staticmethod
    def get_chart(type: str) -> Chat:
        if type == "histogram":
            return HistogramChart()
        elif type == "pie":
            return PieChart()
        elif type == "line":
            return LineChart()


# 客户端测试代码
chart = ChartFactory.get_chart("line")
chart.display()


### 输出结果
创建折线图
显示折线图

三、简单工厂模式客户端改进

创建具体Chart对象时,每更换一个Chart对象都需要修改客户端代码中静态工厂方法的参数,客户端代码将要重新编译,这对于客户端而言,违反了开闭原则

  • 引入配置文件config.json和,从配置文件提取图表类型。如果需要更换具体图表对象,只需修改配置文件,无须修改任何源代码。
{
    "chart_type": "histogram"
}
  • JsonUtil工具类
# 模块 utils.py
from pathlib import Path
import json

class JsonUtil:
    @staticmethod
    def get_chart_type():
        path = Path("config.json")
        contents = path.read_text(encoding="utf-8")
        conf = json.loads(contents)
        return conf.get("chart_type", None)
  • 改进后客户端代码
from utils import JsonUtil

chart_type = JsonUtil.get_chart_type()
chart = ChartFactory.get_chart(chart_type)
chart.display()


### 输出结果
创建柱状图
显示柱状图

您正在阅读的是《设计模式Python版》专栏!关注不迷路~

;