「聊设计模式」之简单工厂模式(Simple Factory)

🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎关注&&收藏&&订阅!


前言

在软件开发过程中,我们常会遇到需要创建不同对象的情况,但是很多时候客户端并不需要关心对象的具体创建过程,只需要得到一个可以处理业务逻辑的对象。在这种情况下,使用简单工厂模式可以让客户端无需了解对象的创建细节,只需要向工厂请求所需对象即可。

摘要

简单工厂模式属于创建型模式,它提供了一种创建对象的方式,将对象的创建过程封装在工厂中,客户端只需要调用工厂的创建方法即可得到所需对象。简单工厂模式可以根据传入参数的不同返回不同的对象实例,这种方式属于静态工厂方法,因为它使用了静态方法来创建对象。

简单工厂模式

设计原则

简单工厂模式是实现其他设计模式的基础,不仅能够让客户端更方便地获取所需对象,并且有利于解耦,提高代码的灵活性和可维护性。简单工厂模式的设计原则如下:

  • 单一职责原则:工厂类负责对象的创建,客户端只负责向工厂请求对象。
  • 开闭原则:简单工厂模式可以根据需要添加新的产品类,同时不需要修改工厂类代码,符合开闭原则。
  • 依赖倒置原则:客户端只依赖于工厂类,不依赖于具体产品类。

工厂角色

  • 工厂角色是简单工厂模式的核心,负责实现简单工厂模式的创建过程。

  • 工厂角色主要包含一个 createProduct() 方法,用来创建具体产品角色的实例对象。

抽象产品角色

  • 抽象产品角色是具体产品角色的父类,定义了具体产品角色所需的方法。

具体产品角色

  • 具体产品角色是工厂角色所创建的对象。

  • 具体产品角色实现了抽象产品角色中所定义的方法。

简单工厂模式代码模拟

如下便通过Java代码实现一个简单地工厂模式,同学们认真看,其中的模式是如何运转的,演示如下:

定义抽象产品类

定义一个抽象产品类,其中定义一个无返回值的抽象方法execute();在简单工厂模式中,该接口通常代表着由工厂生产出的产品。所有具体的产品类都需要实现该接口,并且实现该接口的方法。

java 复制代码
package com.example.javaDesignPattern.simpleFactory;

/**
 * 抽象产品类
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/9/18 15:36
 */
public interface Product {
    void execute();
}

简单工厂模式的核心思想是将对象的创建过程封装在一个工厂类中,客户端只需要通过传递不同的参数,就可以获得不同的产品实例。这样,客户端和具体产品的耦合就可以降低,同时也方便了产品的扩展和维护。

整个简单工厂模式中,抽象产品类Product是一个非常重要的组成部分。通过定义抽象产品类,可以将具体产品类的共性进行抽象,使得客户端能够更加方便的使用不同的产品,同时也保证了产品的可扩展性和可维护性。

定义具体产品类

定义一个产品类:ConcreteProductA

java 复制代码
package com.example.javaDesignPattern.simpleFactory;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/18 15:36
 */
public class ConcreteProductA implements Product {
    @Override
    public void execute() {
        System.out.println("执行具体产品A的方法");
    }
}

定义一个产品类:ConcreteProductB

java 复制代码
package com.example.javaDesignPattern.simpleFactory;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/18 15:37
 */
public class ConcreteProductB implements Product {
    @Override
    public void execute() {
        System.out.println("执行具体产品B的方法");
    }
}

代码解读: 抽象产品类 Product 定义了所有具体产品类(如 ConcreteProductA 和 ConcreteProductB)所需实现的方法。具体产品类则用于实现这些方法。 在该示例中,ConcreteProductA 和 ConcreteProductB 分别实现了 execute() 方法以输出不同的信息。

定义工厂类

java 复制代码
package com.example.javaDesignPattern.simpleFactory;

/**
 * 工厂类
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/9/18 15:41
 */
public class Factory {
    public static Product createProduct(String type) {
        //根据传入的参数type的不同来创建不同的产品对象。
        if (type.equals("A")) {
            return new ConcreteProductA();
        } else if (type.equals("B")) {
            return new ConcreteProductB();
        } else {
            throw new IllegalArgumentException("Unknown product type: " + type);
        }
    }
}

代码解读:

如上代码展现了一个简单的工厂模式的实现,通过一个静态方法createProduct,根据传入的参数type的不同来创建不同的产品对象,返回的是一个Product类型的实例对象。具体实现是通过if-else语句来判断传入参数的类型,然后返回相应类型的ConcreteProduct实例对象。如果传入的类型不是A或B,会抛出一个IllegalArgumentException异常。工厂模式可以帮助我们封装对象的创建过程,避免直接使用new关键字来创建对象,降低代码的耦合度。

测试用例

下面是使用简单工厂模式的测试用例,客户端只需要调用工厂的创建方法即可获取所需对象:

java 复制代码
package com.example.javaDesignPattern.simpleFactory;

/**
 * 客户端
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/9/18 15:42
 */
public class Client {

    public static void main(String[] args) {
        Product productA = Factory.createProduct("A");
        Product productB = Factory.createProduct("B");

        productA.execute();
        productB.execute();
    }
}

根据如上测试用例执行结果如下:

解读:在这个例子中,工厂类 Factory,它负责根据参数创建具体的产品类对象。这些产品类都实现了同一个接口 Product,对外提供了 execute 方法。Client 类是客户端类,它通过工厂类创建了两个不同的产品对象 productA 和 productB,并调用它们的 execute 方法。

工厂模式的作用是将产品的创建和使用分离,客户端只需要知道需要什么类型的产品,而不需要知道具体的实现细节。这样做的好处是,当需要修改产品实现时,只需要修改工厂类的代码即可,客户端不受影响。同时,工厂模式也可以避免客户端直接依赖具体的产品类,降低了代码的耦合度,提高了代码的可维护性和扩展性。

优缺点

使用简单工厂模式的优点包括:

  • 封装了对象的创建过程,客户端无需知道具体对象的创建过程,只需要调用工厂方法即可获取所需对象。
  • 简单工厂模式提供了一种快速创建对象的方式,便于在代码中重复使用相同的对象。
  • 开闭原则,可以轻松地添加新的产品类。

使用简单工厂模式的缺点包括:

  • 工厂类负责创建所有产品对象,当产品种类过多时,工厂类代码会变得非常臃肿。
  • 简单工厂模式使用静态工厂方法,如果需要添加新的产品类,则需要修改工厂类的代码。
  • 违反了开闭原则,因为添加新的产品类需要修改工厂类的代码。

小结

本文主要介绍了简单工厂模式的基本概念和代码实现。简单工厂模式通过工厂角色的创建过程将对象的创建交给工厂类来实现,这样可以简化对象的创建过程。

附录源码

如上涉及代码均已上传同步在GitHub,提供给同学们参考性学习。

总结

简单工厂模式是工厂模式的一种,它通过一个工厂类,来根据用户提供的参数,创建产品类的实例。这种模式将对象的创建和使用分离,用户只需要知道需要什么产品即可,无需了解产品的创建细节。简单工厂模式的优点在于简单、易于管理和扩展,但是缺点也很明显------增加新的产品需要修改工厂类的逻辑。因此,在实际开发中,我们需要根据具体的场景来选择使用哪种工厂模式。

☀️建议/推荐你


如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

📣关于我


我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。

相关推荐
Dola_Pan28 分钟前
Linux文件IO(二)-文件操作使用详解
java·linux·服务器
wang_book31 分钟前
Gitlab学习(007 gitlab项目操作)
java·运维·git·学习·spring·gitlab
蜗牛^^O^1 小时前
Docker和K8S
java·docker·kubernetes
从心归零2 小时前
sshj使用代理连接服务器
java·服务器·sshj
IT毕设梦工厂3 小时前
计算机毕业设计选题推荐-在线拍卖系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
Ylucius4 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
凡人的AI工具箱4 小时前
AI教你学Python 第11天 : 局部变量与全局变量
开发语言·人工智能·后端·python
是店小二呀4 小时前
【C++】C++ STL探索:Priority Queue与仿函数的深入解析
开发语言·c++·后端
七夜zippoe4 小时前
分布式系统实战经验
java·分布式
canonical_entropy4 小时前
金蝶云苍穹的Extension与Nop平台的Delta的区别
后端·低代码·架构