软件设计模式系列之四——简单工厂模式

2023-09-13 07:10:33

1 模式的定义

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,用于对象的创建,它属于工厂模式的一种。简单工厂模式的主要目标是封装对象的创建过程,使客户端代码与具体类的实例化解耦,从而提高代码的可维护性和可扩展性。

简单工厂模式定义了一个工厂类,该工厂类负责根据客户端的需求创建不同类型的对象,而客户端只需提供一个参数或者条件,工厂类就能返回相应的具体对象实例。

2 举例说明

在这里插入图片描述

利用富士康代工生产小米手机、华为手机为例来说明一下简单工厂模式,其中

富士康工厂就是简单工厂,负责根据客户(小米和华为)的要求来制造手机。

小米手机和 华为手机 是具体的产品,它们有不同的特性和功能,但都属于手机产品。

在这个例子中,富士康工厂就像是一个手机制造工厂,客户(小米和华为)只需要向工厂提出订单(传递一个参数或条件,例如手机品牌),工厂根据客户的要求生产出相应的手机产品。客户不需要了解手机制造的具体细节,只需与工厂交互即可。这种方式将手机的创建过程与客户代码解耦,使得客户端更加简洁,并且富士康工厂可以根据市场需求轻松地生产不同品牌的手机,而不需要修改客户端代码。

简单工厂模式在这个例子中帮助了富士康工厂代工制造手机,客户只需要告诉工厂需要哪种手机,而无需关心手机的具体制造过程,这体现了简单工厂模式的核心思想,即将对象的创建与客户端代码解耦,从而提高了灵活性和可维护性。

3 结构

简单工厂模式的结构主要包括以下三个关键元素:

在这里插入图片描述

  • 具体产品类(Concrete Products)

具体产品类是工厂类创建的对象类型,它们共享一个公共的抽象产品类或接口。每个具体产品类实现了抽象产品类或接口中定义的方法,以提供特定的功能和行为。

  • 工厂类(Factory)

工厂类是简单工厂模式的核心部分,负责根据客户端的请求创建具体产品对象。工厂类通常包含一个或多个工厂方法,每个工厂方法用于创建不同类型的具体产品对象。工厂类的目标是封装对象的创建逻辑,使客户端免于了解具体产品的构造过程。

  • 客户端(Client)

客户端是使用简单工厂模式的代码部分,负责向工厂类发送请求以获取所需的具体产品对象。客户端通常不直接实例化具体产品对象,而是通过工厂类来获取对象。

简单工厂模式的关键思想是将对象的创建和客户端解耦,客户端只需要知道如何使用工厂类来获取所需的对象,而无需关心对象的具体创建过程。这种模式有助于提高代码的可维护性和可扩展性,因为它允许在不修改客户端代码的情况下添加新的具体产品类。

4 实现步骤

简单工厂模式的实现步骤如下:

4.1 定义抽象产品类(Abstract Product)

首先,定义一个抽象产品类或接口,它声明了具体产品类必须实现的方法。这个抽象产品类将统一具体产品的接口。

4.2 创建具体产品类(Concrete Products)

为每个具体产品创建一个相应的类,这些类应该实现抽象产品类中定义的方法。

具体产品类表示不同类型的对象,具体产品的特性和行为由这些类来定义。

4.3 创建工厂类(Factory)

创建一个工厂类,该工厂类负责对象的创建。

在工厂类中定义一个或多个工厂方法,用于根据客户端的请求创建具体产品对象。

工厂方法通常会包括条件判断或者其他逻辑,以确定创建哪个具体产品对象。

4.4 客户端使用工厂类

客户端不直接实例化具体产品对象,而是通过调用工厂类的方法来获取所需的对象。

客户端需要知道如何使用工厂类,以及如何传递参数或条件给工厂类来获取合适的对象。

4.5 客户端调用工厂方法

客户端在需要具体产品对象的地方,调用工厂方法并传递必要的参数或条件。

工厂方法会根据参数或条件来创建并返回相应的具体产品对象。

总的来说,简单工厂模式通过将对象的创建逻辑封装在工厂类中,使客户端代码与具体产品的构造过程解耦,从而提高了代码的可维护性和可扩展性。客户端只需要关注如何使用工厂类来获取对象,而无需了解对象的创建细节。这种模式适用于那些对象的创建过程相对简单,不需要频繁变化的场景。

5 代码实现

首先,定义抽象手机类 AbstractMobile,其中只包含一个抽象方法 action

public abstract class AbstractMobile {
    public abstract void action();
}
</code></div></div></pre>

接下来,创建具体手机类 XiaomiMobileHuaweiMobile,它们分别继承自 AbstractMobile 并实现 action 方法:

public class XiaomiMobile extends AbstractMobile {
    @Override
    public void action() {
        System.out.println("Xiaomi Mobile is performing an action.");
    }
}

public class HuaweiMobile extends AbstractMobile {
    @Override
    public void action() {
        System.out.println("Huawei Mobile is performing an action.");
    }
}

然后,创建工厂类 FuFactory,该工厂类包含一个方法 createMobile 用于根据客户端的需求创建具体产品对象:

public class FuFactory {
    public static AbstractMobile createMobile(String brand) {
        if ("Xiaomi".equals(brand)) {
            return new XiaomiMobile();
        } else if ("Huawei".equals(brand)) {
            return new HuaweiMobile();
        } else {
            throw new IllegalArgumentException("Invalid brand. Supported brands are Xiaomi and Huawei.");
        }
    }
}

最后,客户端代码可以使用 FuFactory 来创建手机对象,并调用 action 方法:

public class Main {
    public static void main(String[] args) {
        AbstractMobile xiaomiPhone = FuFactory.createMobile("Xiaomi");
        AbstractMobile huaweiPhone = FuFactory.createMobile("Huawei");

        xiaomiPhone.action();
        huaweiPhone.action();
    }
}

这段 Java 代码将输出以下结果:

Xiaomi Mobile is performing an action.
Huawei Mobile is performing an action.

这个示例中,我们定义了一个抽象方法 action,要求具体手机类必须实现该方法。通过简单工厂模式,我们成功地创建了 XiaomiMobileHuaweiMobile 对象,并在客户端代码中调用了 action 方法。这种方式可以确保每个具体手机类都必须提供一个特定的行为实现。

6 典型应用场景

简单工厂模式适用于以下应用场景:
在这里插入图片描述
需要根据条件创建不同对象的情况 :当系统中的某个类有多个子类,而客户端在不同情况下需要创建不同子类的对象时,可以使用简单工厂模式。通过简单工厂,客户端只需提供条件或参数,而无需了解对象的具体构造过程。

对象的创建过程相对简单 :如果对象的创建逻辑相对简单,不涉及复杂的初始化操作或依赖关系的管理,那么简单工厂模式是一个合适的选择。它有助于将创建逻辑集中在一个工厂类中,提高了代码的可维护性。

需要降低客户端和具体产品类之间的耦合度 :通过简单工厂模式,客户端代码与具体产品类之间的耦合度降低,因为客户端只需要与工厂类交互,而无需直接与具体产品类交互。这使得客户端更加灵活,能够轻松适应变化。

需要在系统中集中管理对象的创建逻辑 :如果希望在整个系统中集中管理对象的创建逻辑,可以使用简单工厂模式。这有助于在将来的维护和扩展中更容易地修改或添加新的产品类。

对象创建频率较低 :如果某种类型的对象在系统中的创建频率相对较低,而且不需要支持多态性,简单工厂模式可以满足需求,避免创建大量的工厂方法。

需要注意的是,虽然简单工厂模式有其优点,但它也有一些缺点,例如不符合开闭原则,因为每次添加新的产品类都需要修改工厂类,可能导致工厂类变得庞大。因此,在某些情况下,工厂方法模式或抽象工厂模式可能更适合处理对象的创建需求。选择适当的创建型模式取决于具体的项目需求和设计目标。

7 优缺点

简单工厂模式有一些优点和缺点,下面是简单工厂模式的主要优缺点:

优点:

  • 封装对象创建过程 :简单工厂模式将对象的创建过程封装在工厂类中,使客户端无需关心对象的具体构造过程,从而降低了客户端代码与具体产品类之间的耦合度。
  • 代码重用 :通过工厂类来创建对象,可以在不同的地方多次使用相同的创建逻辑,提高了代码的重用性。
  • 集中管理 :简单工厂模式将对象的创建逻辑集中管理,有助于在系统中统一管理对象的创建,便于维护和修改。
  • 客户端简化 :客户端代码只需要与工厂类交互,无需了解具体产品类的细节,使客户端代码更加简洁和易懂。
  • 降低错误风险 :通过工厂类创建对象可以减少客户端可能出现的错误,因为客户端无法直接实例化具体产品类。

缺点:

  • 违反开闭原则 :每次添加新的具体产品类都需要修改工厂类,违反了开闭原则(对扩展开放,对修改关闭)。这可能导致工厂类变得庞大,影响代码的可维护性。
  • 不支持多态性 :简单工厂模式不能很好地支持多态性,因为所有的对象创建逻辑都集中在一个工厂类中,无法实现不同产品的不同工厂,导致无法使用多态来处理对象。
  • 工厂类职责过重 :随着具体产品类的增加,工厂类可能会变得庞大,包含大量的分支逻辑,不利于维护和扩展。
  • 可定制性有限 :简单工厂模式的定制性较低,因为工厂类负责所有产品的创建,如果需要针对不同客户定制不同的创建逻辑,可能不太适用。

8 类似模式

简单工厂模式是创建型设计模式之一,它通过一个工厂类来创建对象,客户端只需要提供一个参数或条件,工厂类就能返回相应的具体对象实例。这种模式适用于对象的创建相对简单的情况,但不支持多态性,每次添加新的产品类都需要修改工厂类。

工厂方法模式是建立在简单工厂模式的基础上的进一步抽象和扩展,它将对象的创建延迟到子类。每个具体产品类都有对应的工厂类,客户端通过与工厂接口或抽象类交互,具体产品的创建由子类工厂来完成。工厂方法模式支持多态性,允许不同的具体工厂创建不同的产品对象。

抽象工厂模式是创建型设计模式,它提供一个接口或抽象类来创建一系列相关或相互依赖的对象,而无需指定它们的具体类。抽象工厂模式通常用于创建一组有关联的产品,例如在制造电子设备时,可能需要同时创建屏幕、主板、CPU等相关组件,抽象工厂能够确保这些组件之间的兼容性。这种模式支持多态性,并且允许客户端使用不同的具体工厂创建一组相关的产品。

这三种模式之间的关系可以看作是一种逐步抽象和扩展的关系。简单工厂模式是最简单的工厂模式,它将对象的创建过程封装在一个工厂类中。工厂方法模式在简单工厂的基础上引入了多态性,通过子类工厂来创建不同类型的产品。抽象工厂模式进一步抽象,它用于创建一组相关的产品,并提供一种更高级别的抽象,以确保这些产品之间的协调和兼容。选择使用哪种工厂模式取决于具体的项目需求和设计目标。

9 小结

总的来说,简单工厂模式适用于对象创建过程相对简单且稳定的情况,能够有效地将对象的创建与使用分离,提高代码的可维护性和可扩展性。但在需要频繁添加新的具体产品类或需要支持多态性的情况下,工厂方法模式或抽象工厂模式可能更适合。选择适当的创建型模式取决于具体的项目需求和设计目标。

更多推荐

【计算机毕业设计】基于SpringBoot+Vue贵州旅游系统的设计与实现

博主主页:一季春秋博主简介:专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发,远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容:毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题库、技术咨询。🍅文末获取联系🍅精彩专栏推荐订阅👇🏻👇🏻不然下次找不到哟Sp

0/17 SAP Master Data Governance(SAP 主数据治理)

SAPMasterDataGovernanceTheComprehensiveGuidetoSAPMDG(SAP主数据治理-SAPMDG综合指南)HowThisBookIsOrganized这本书是如何组织的Chapter1Thischapterstartswithanintroductionintothevariou

C++ 太卷,转 Java?

最近看到知乎、牛客等论坛上关于C++很多帖子,比如:2023年大量劝入C++2023年还建议走C++方向吗?看了一圈,基本上都是说C++这个领域唯一共同点就是都使用C++语言,其它几乎没有相关性。的确是这样,比如量化交易、自动驾驶,客户端,图形学,存储数据库开发,后台开发,嵌入式等等基本上都有各自的领域知识。那么为什么

循环经济下的新赛道妃鱼助力二手奢侈品行业变革

自2016年以来,随着国家对于闲置物品利用的政策文件连续发布,我们可以明确地看到一个趋势:我国正在积极鼓励和支持循环经济的发展,这不仅是政策层面的指导,更是反映了新一代消费者的消费观念的转变,在这样的大背景趋势下,二手奢侈品市场开始崭露头角,国泰君安研究报告显示,中国闲置高端消费品零售市场规模已从2016年162亿元增

【光伏系统】将电流从直流转换为交流电的太阳能逆变器、太阳能跟踪系统来提高系统的整体性能及集成电池解决方案(Simulink仿真)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1概述📚2运行结果🎉3参考文献🌈4Simulink仿真实现💥1概述本文介绍了太阳能仿真技术及其各个组成部分。太阳

NoSQL之 Redis配置与优化

目录1、关系数据库与非关系型数据库1.1关系型数据库1.2非关系型数据库1.3关系型数据库和非关系型数据库区别1.4非关系型数据库产生背景2、Redis2.1简介2.2Redis具有以下几个优点2.3Redis为什么这么快?3、Redis安装部署3.1Redis命令工具3.2redis-cli命令行工具3.3redis

金融领域:产业链知识图谱包括上市公司、行业和产品共3类实体,构建并形成了一个节点10w+,关系边16w的十万级别产业链图谱

项目设计集合(人工智能方向):助力新人快速实战掌握技能、自主完成项目设计升级,提升自身的硬实力(不仅限NLP、知识图谱、计算机视觉等领域):汇总有意义的项目设计集合,助力新人快速实战掌握技能,助力用户更好利用CSDN平台,自主完成项目设计升级,提升自身的硬实力。专栏订阅:项目大全提升自身的硬实力[专栏详细介绍:项目设计

SpaceX预计到2022年Starlink用户将达到2000万,但最终达到了100万

SpaceX的Starlink部门还没有接近实现客户和收入的预测,该公司在建立卫星网络之前与投资者分享了这一点华尔街日报报道今天出版。据报道,2015年的一份题为“SpaceX用来从投资者那里筹集资金”的报告预计,到2022年,Starlink的订户将达到2000万人,并产生近120亿美元的收入和70亿美元的营业利润。

【LLM】金融大模型场景和大模型Lora微调实战

文章目录一、金融大模型背景二、大模型的研究问题三、大模型技术路线四、LLaMA家族模型五、Lora模型微调的原理六、基于mt0-large进行Lora微调实战七、对chatglm2进行lora微调Reference一、金融大模型背景金融行业需要垂直领域LLM,因为存在金融安全和数据大多数存储在本地,在风控、精度、实时性

基于中文金融知识的 LLaMA 系微调模型的智能问答系统:LLaMA大模型训练微调推理等详细教学

项目设计集合(人工智能方向):助力新人快速实战掌握技能、自主完成项目设计升级,提升自身的硬实力(不仅限NLP、知识图谱、计算机视觉等领域):汇总有意义的项目设计集合,助力新人快速实战掌握技能,助力用户更好利用CSDN平台,自主完成项目设计升级,提升自身的硬实力。专栏订阅:项目大全提升自身的硬实力[专栏详细介绍:项目设计

malloc与free

目录前提须知:malloc:大意:头文件:申请空间:判断是否申请成功:使用空间:结果:整体代码:malloc申请的空间怎么回收呢?注意事项:free:前提须知:为什么要有动态内存分配?我们已经掌握的内存开辟⽅式有:intval=20;//在栈空间上开辟四个字节chararr[10]={0};//在栈空间上开辟10个字节

热文推荐