简单工厂模式(Simple Factory Pattern)详解


一、简单工厂模式简介

简单工厂模式(Simple Factory Pattern) 并不是 GoF 提出的 23 种设计模式之一,但它是一种常见的设计模式,属于创建型模式(类创建型模式)。它提供了一种通过专门的工厂类来创建对象的方法,而不是直接在客户端代码中实例化具体的类。
定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

简单来说:

“简单工厂模式就像是一个‘造物主’,根据传入的不同参数决定生产哪种具体产品。”

简单工厂模式基本实现流程
具体产品类:将需要创建的各种不同产品对象的相关代码封装到具体产品类中

抽象产品类:将具体产品类公共的代码进行抽象和提取后封装在一个抽象产品类中

工厂类:提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入参数的不同创建不同的具体产品对象

客户端:只需调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象

在简单工厂模式中用于创建实例的方法通常是静态(static)方法,因此又被称为静态工厂方法(Static Factory Method)模式
要点:如果需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无须知道其创建细节。

简单工厂模式包含以下3个角色
Factory(工厂角色)
Product(抽象产品角色)
ConcreteProduct(具体产品角色)

在这里插入图片描述


二、解决的问题类型

简单工厂模式主要用于解决以下问题:

  • 需要隐藏对象的创建逻辑:避免让客户端直接使用 new 关键字实例化具体类。
  • 简化客户端代码:将对象创建的责任转移到工厂类中,使客户端只需调用工厂方法即可获取所需对象。
  • 支持扩展性:新增产品时只需要修改工厂类,无需改动已有客户端代码。

三、使用场景

场景示例
创建复杂对象如复杂的数据库连接池或网络请求等
多个相似的产品如不同类型的支付方式(支付宝、微信、银联)
统一管理对象的创建过程避免在多个地方重复编写相同的构造逻辑

工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂
客户端只知道传入工厂类的参数,对于如何创建对象并不关心


四、核心概念

  1. Factory(工厂类):负责根据输入参数决定并创建相应的具体产品对象。
  2. Product(抽象产品接口/基类):定义所有产品的公共接口或基类。
  3. ConcreteProduct(具体产品类):实现抽象产品接口的具体产品类。

五、实际代码案例(Java)

我们以“计算器”为例,演示简单工厂模式的使用。假设我们需要根据不同运算符执行加法、减法等操作。

1. 定义抽象产品接口

// 运算接口
public interface Operation {
    double calculate(double num1, double num2);
}

2. 创建具体产品类

// 加法类
public class Addition implements Operation {
    @Override
    public double calculate(double num1, double num2) {
        return num1 + num2;
    }
}

// 减法类
public class Subtraction implements Operation {
    @Override
    public double calculate(double num1, double num2) {
        return num1 - num2;
    }
}

// 乘法类
public class Multiplication implements Operation {
    @Override
    public double calculate(double num1, double num2) {
        return num1 * num2;
    }
}

3. 创建工厂类

public class OperationFactory {

    // 根据运算符返回对应的操作对象
    public static Operation createOperation(String operator) {
        switch (operator) {
            case "+":
                return new Addition();
            case "-":
                return new Subtraction();
            case "*":
                return new Multiplication();
            default:
                throw new IllegalArgumentException("Unsupported operation: " + operator);
        }
    }
}

4. 客户端测试类

public class Client {
    public static void main(String[] args) {
        // 使用简单工厂创建加法操作
        Operation addition = OperationFactory.createOperation("+");
        System.out.println("10 + 5 = " + addition.calculate(10, 5));

        // 使用简单工厂创建减法操作
        Operation subtraction = OperationFactory.createOperation("-");
        System.out.println("10 - 5 = " + subtraction.calculate(10, 5));

        // 使用简单工厂创建乘法操作
        Operation multiplication = OperationFactory.createOperation("*");
        System.out.println("10 * 5 = " + multiplication.calculate(10, 5));
    }
}

输出结果:

10 + 5 = 15.0
10 - 5 = 5.0
10 * 5 = 50.0

典型代码

典型的抽象产品类代码:

abstract class Product
{
     //所有产品类的公共业务方法
public void MethodSame() 
{
    //公共方法的实现
}

//声明抽象业务方法
public abstract void MethodDiff();
}

典型的具体产品类代码:

class ConcreteProductA : Product
{
    //实现业务方法
    public override void MethodDiff()
    {
        //业务方法的实现
    }
}

典型的工厂类代码:

class Factory
{
    //静态工厂方法
    public static Product GetProduct(string arg)
    {
        Product product = null;
        if (arg.Equals("A"))
        {
            product = new ConcreteProductA();
            //初始化设置product
        }
        else if (arg.Equals("B"))
        {
            product = new ConcreteProductB();
            //初始化设置product
        }
        return product;
    }
}

典型的客户端代码:

class Program
{
    static void Main(string[] args)
    {
        Product product;
        product = Factory.GetProduct("A"); //通过工厂类创建产品对象
        product.MethodSame();
        product.MethodDiff();
    }
}

其他案例

  1. 某软件公司要基于C#语言开发一套图表库,该图表库可以为应用系统提供多种不同外观的图表,例如柱状图(HistogramChart)、饼状图(PieChart)、折线图(LineChart)等。该软件公司图表库设计人员希望为应用系统开发人员提供一套灵活易用的图表库,通过设置不同的参数即可得到不同类型的图表,而且可以较为方便地对图表库进行扩展,以便能够在将来增加一些新类型的图表。
    现使用简单工厂模式来设计该图表库。

在这里插入图片描述

  1. 简单电视机工厂
    某电视机厂专为各知名电视机品牌代工生产各类电视机,当需要海尔牌电视机时只需要在调用该工厂的工厂方法时传入参数“Haier”,需要海信电视机时只需要传入参数“Hisense”,工厂可以根据传入的不同参数返回不同品牌的电视机。现使用简单工厂模式来模拟该电视机工厂的生产过程。

在这里插入图片描述

  1. 权限管理
    在某OA系统中,系统根据对比用户在登录时输入的账号和密码以及在数据库中存储的账号和密码是否一致来进行身份验证,如果验证通过,则取出存储在数据库中的用户权限等级(以整数形式存储),根据不同的权限等级创建不同等级的用户对象,不同等级的用户对象拥有不同的操作权限。现使用简单工厂模式来设计该权限管理模块。

在这里插入图片描述

将对象的创建与使用分离的其他好处
防止用来实例化一个类的数据和代码在多个类中到处都是,可以将有关创建的知识搬移到一个工厂类中,解决代码重复、创建蔓延的问题
构造函数的名字都与类名相同,从构造函数和参数列表中大家很难了解不同构造函数所构造的产品的差异 --> 将对象的创建过程封装在工厂类中,可以提供一系列名字完全不同的工厂方法,每一个工厂方法对应一个构造函数,客户端可以以一种更加可读、易懂的方式来创建对象


六、优缺点分析

优点描述
解耦客户端与具体产品类客户端不需要知道如何创建具体的产品对象
便于维护和扩展新增产品只需修改工厂类,不影响现有代码
简化客户端代码客户端只需调用工厂方法获取所需对象
缺点描述
违反开闭原则工厂类需要根据新需求修改,不完全符合开闭原则
增加系统复杂度对于少量产品的情况,引入工厂类反而增加了系统的复杂度
单一职责问题工厂类可能变得过于庞大,承担过多责任

七、与其他模式对比(补充)

模式名称目标
工厂方法模式提供一个创建对象的接口,但由子类决定实例化哪一个类
抽象工厂模式提供一系列相关或相互依赖对象的创建,而不指定它们具体的类
简单工厂模式通过静态方法集中创建对象,简化了对象的创建过程

八、最终小结

简单工厂模式是一种非常基础且实用的设计模式,特别适合那些需要统一管理和创建一组相似对象的场景。虽然它存在一些局限性,如违反开闭原则,但对于小型项目或者初期快速开发阶段,简单工厂模式能够有效地提高代码的可读性和可维护性。

在开发工具类库、框架、服务层接口等场景下,简单工厂模式可以帮助你更好地组织代码结构,减少重复代码。


📌 一句话总结:

简单工厂模式就像一个“万能钥匙”,无论你需要哪种类型的对象,只要告诉工厂你的需求,它就能为你生成相应的实例。


推荐使用场景:

  • 当你有一组相似的产品需要创建时;
  • 希望将对象创建的逻辑集中在一个地方进行管理;
  • 不希望客户端直接接触具体的产品类。

九、创建型模式

创建型模式(Creational Pattern)关注对象的创建过程。

创建型模式对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离,对用户隐藏了类的实例的创建细节。

创建型模式描述如何将对象的创建和使用分离,让用户在使用对象时无须关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修改和扩展。

创建型模式关注点
创建什么(What)
由谁创建(Who)
何时创建(When)
创建对象,使用对象

创建型模式
在这里插入图片描述

十、其他

何时不需要工厂?
无须为系统中的每一个类都配备一个工厂类。
如果一个类很简单,而且不存在太多变化,其构造过程也很简单,此时就无须为其提供工厂类,直接在使用之前实例化即可。
否则会导致工厂泛滥,增加系统的复杂度
例如:string类

简单工厂模式的简化
将抽象产品类和工厂类合并,将静态工厂方法移至抽象产品类中

在这里插入图片描述

以上部分内容由AI大模型生成,注意识别!

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐