深入理解与应用工厂方法模式

文章目录

  • 一、模式概述
  • **二、适用场景**
  • **三、模式原理与实现**
  • **四、采用工厂方法模式的原因**
  • **五、优缺点分析**
  • **六、与抽象工厂模式的比较**
  • 总结

一、模式概述

​ 工厂方法模式是一种经典的设计模式,它遵循面向对象的设计原则,特别是“开闭原则”,通过定义一个用于创建对象的接口,将对象的实例化过程推迟到子类中实现。这种模式与抽象工厂模式类似,但更加专注于对单一接口下产品类型的创建。

二、适用场景

  • 复杂对象的创建需要大量重复代码时。
  • 对象创建依赖于外部资源或信息。
  • 需要统一管理对象生命周期,如会话、资源池对象等。
  • 需要隐藏对象的具体类型,提高代码的抽象层次。

以 MyBatis 的 LogFactory 类为例,展示了工厂方法模式如何应用于实际项目中,通过灵活的选择和初始化不同日志实现类(如 Slf4j、Log4j 等),达到按需创建和管理日志对象的目的。

三、模式原理与实现

​ 工厂方法模式的核心在于封装对象的创建过程,提高对象创建的可复用性。通过观察代码实现可知,核心工厂类并不直接创建具体产品,而是通过判断条件委派给子类,从而使得在不修改核心工厂的前提下能够引入新的产品实现。

工厂方法模式的核心组成部分包括:

在这里插入图片描述

  1. 抽象产品(Abstract Product):定义产品的公共接口,如 IProduct 接口。
  2. 核心工厂(Concrete Factory):如 ProductFactory 类,提供创建产品实例的通用接口,根据传入的参数决定创建何种具体产品。
  3. 具体产品(Concrete Products):如 Product_A_ImplProduct_B_Impl 类,它们实现抽象产品接口,提供了具体产品的实例化过程。

以下是工厂方法模式的一个详细代码示例,创建一个动物工厂,它可以创建各种类型的动物对象:

首先,我们定义一个抽象的动物接口(抽象产品):

// 抽象产品
public interface Animal {
    void makeSound();
}

然后,我们创建几个实现了 Animal 接口的具体动物类(具体产品):

// 具体产品:Dog 类
public class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

// 具体产品:Cat 类
public class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow! Meow!");
    }
}

接下来,我们定义一个抽象工厂类,它声明了一个创建动物对象的方法:

// 抽象工厂
public abstract class AnimalFactory {
    public abstract Animal createAnimal(String animalType);
}

然后,我们创建两个具体工厂类,它们实现了上述抽象工厂类,并在其中定义了如何创建具体动物对象:

// 具体工厂:DogFactory 类
public class DogFactory extends AnimalFactory {
    @Override
    public Animal createAnimal(String animalType) {
        if ("dog".equalsIgnoreCase(animalType)) {
            return new Dog();
        }
        throw new IllegalArgumentException("Invalid animal type");
    }
}

// 具体工厂:CatFactory 类
public class CatFactory extends AnimalFactory {
    @Override
    public Animal createAnimal(String animalType) {
        if ("cat".equalsIgnoreCase(animalType)) {
            return new Cat();
        }
        throw new IllegalArgumentException("Invalid animal type");
    }
}

最后,我们通过客户端代码来演示如何使用工厂方法模式创建并使用动物对象:

public class Client {
    public static void main(String[] args) {
        // 使用 DogFactory 创建 Dog 对象
        AnimalFactory dogFactory = new DogFactory();
        Animal dog = dogFactory.createAnimal("dog");
        dog.makeSound();  // 输出:Woof! Woof!

        // 使用 CatFactory 创建 Cat 对象
        AnimalFactory catFactory = new CatFactory();
        Animal cat = catFactory.createAnimal("cat");
        cat.makeSound();  // 输出:Meow! Meow!
    }
}

测试结果

在这里插入图片描述

​ 在这个示例中,AnimalFactory 是抽象工厂,DogFactoryCatFactory 是具体工厂,DogCat 是具体产品。客户端代码通过工厂方法来获取具体产品,而无需直接创建产品对象,这样就实现了对象的创建和使用相分离,同时也易于扩展新的产品类型。

四、采用工厂方法模式的原因

  1. 分离对象创建与使用:降低耦合性,增强代码的可维护性与可扩展性。
  2. 减少重复代码:通过工厂类集中处理相似对象的创建逻辑,避免代码冗余。
  3. 管理创建逻辑的变化:当业务逻辑发生变化时,只需修改工厂类的实现,无需改动大量调用处。

五、优缺点分析

  • 优点:支持灵活定制,隐藏实现细节,符合开闭原则,实现多态性。
  • 缺点:当抽象接口新增方法时,可能导致所有具体工厂都要相应修改;若具体工厂实现逻辑各异,则增加代码理解和维护难度。

六、与抽象工厂模式的比较

​ 尽管工厂方法模式与抽象工厂模式都属于创建型设计模式,但前者更关注于单一接口下产品的创建与替换,强调继承结构的连续性;而后者聚焦于一组相关产品间的协同创建,更看重组合的扩展性,两种模式在实际应用中各有侧重。

总结

​ 工厂方法模式以其简洁的实现和良好的扩展性,在实际项目中广泛使用。在面临对象创建逻辑较为复杂或需要灵活切换产品实现时,它是一种值得考虑的设计解决方案。然而,在简单对象创建场景下,开发者需审慎使用,避免因过度设计引入额外复杂性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/417852.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

EasyX的使用(详解版)

EasyX的基础概念&#xff1a; 图形化——EasyX的安装-CSDN博客 创建图形化窗口 #include<graphics.h> #include<conio.h> int main() {//创建绘图窗口&#xff0c;大小为100x100像素。//更改为大窗口&#xff0c;像素增大&#xff1b;更改为小窗口&#xff0c;像素…

华为数通方向HCIP-DataCom H12-821题库(单选题:481-500)

第481题 以下关于基于SD-WAN思想的EVPN互联方案的描述,错误的是哪一项? A、通过部署独立的控制面,将网络转发和控制进行了分离,从而实现了网络控制的集中化 B、通过对WAN网络抽象和建模,将上层网络业务和底层网络具体实现架构进行解耦,从而实现网络自动化 C、通过集中的…

上位机图像处理和嵌入式模块部署(当前机器视觉新形态)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 过去的机器视觉处理&#xff0c;大部分都是集中在上位机、或者是服务器领域&#xff0c;这种形式维持了很长的时间。这种业务形态下&#xff0c;无…

javaee教程郑阿奇课后答案,三年经验月薪50k我是怎么做到的

个人背景 如标题所示&#xff0c;我的个人背景非常简单&#xff0c;Java开发经验1年半&#xff0c;学历普通&#xff0c;2本本科毕业&#xff0c;毕业后出来就一直在Crud&#xff0c;在公司每天重复的工作对我的技术提升并没有什么帮助&#xff0c;但小镇出来的我也深知自我努…

这一步一步爬的伤痕累累

一、网安专业名词解释 ① CTF CTF&#xff08;Capture The Flag&#xff09;中文一般译作夺旗赛&#xff0c;在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。CTF起源于1996年DEFCON全球黑客大会&#xff0c;以代替之前黑客们通过互相发起真实攻击进…

数据结构-----再谈String,字符串常量池,String对象的创建、intern方法的作用

文章目录 1.字符串常量池1.1. 创建对象的思考2.2. 字符串常量池(StringTable)1.3. 再谈String对象创建1.4. intern方法 1.字符串常量池 1.1. 创建对象的思考 下面两种创建String对象的方式相同吗&#xff1f; public static void main(String[] args) {String s1 "hel…

Jmeter系列(5)线程数到底能设置多大

疑惑 一台设备的线程数到底可以设置多大&#xff1f; 线程数设置 经过一番搜索找到了这样的答案&#xff1a; Linux下&#xff0c;2g的 java内存&#xff0c;1m 的栈空间&#xff0c;最大启动线程数2000线程数建议不超过1000jmeter 能启动多少线程&#xff0c;由你的堆内存…

Decision Transformer

DT个人理解 emmm, 这里的Transformer 就和最近接触到的whisper一样,比起传统Transformer,自己还设计了针对特殊情况的tokens。比如whisper里对SOT,起始时间,语言种类等都指定了特殊tokens去做Decoder的输入和输出。 DT这里的作为输入的Tokens由RL里喜闻乐见的历史数据:…

docker save 命令 docker load 命令 快速复制容器

docker save 命令 docker load 命令 1、docker save 命令2、docker load 命令 1、docker save 命令 docker save 命令用于在系统上把正在使用的某个容器镜像 导出成容器镜像文件保存下载&#xff0c;以便在其他系统上导入这个容器镜像文件 以便快速在其他服务器上启动相同的容…

(正规api接口代发布权限)短视频账号矩阵系统实现开发--技术全自动化saas营销链路生态

短视频账号矩阵系统实现开发--技术全自动化saas营销链路生态源头开发&#xff08;本篇禁止抄袭复刻&#xff09; 一、短视频矩阵系统开发者架构 云罗短视频矩阵系统saas化系统&#xff0c;开发层将在CAP原则基础上使用分布式架构,对此网站的整体架构采用了基于B/S三层架构模式…

使用全局事件总线实现任意组件间的通讯

本文以vue2中爷孙组件通讯为例&#xff0c;需求是点击孙组件的按钮&#xff0c;实现关闭爷组件的弹窗。 全局事件总线是通过Vue实例的事件系统来实现组件之间的通讯&#xff0c;可以方便地在任何组件中进行事件的触发和监听。 以下是使用全局事件总线实现爷孙组件通讯的步骤&a…

33. 【Linux教程】Linux 用户组

前面小节介绍了 Linux 用户相关的增删改查&#xff0c;本小节介绍 Linux 用户组&#xff0c;Linux 系统中采取了一种安全机制&#xff08;即用户组&#xff09;&#xff0c;用户组可以允许多个 Linux 用户共享同一种权限。 1. 用户组介绍 Linux 是多任务多用户的操作系统&…

Vite 构建的 Vue3 项目如何整合 Monaco Editor 代码编辑器

目录 &#x1f981; 一. 前言&#x1f981; 二. 探索过程2.1 安装2.2 配置 Monaco Editor2.3 编写 Monaco Editor 代码编辑器2.3.1 创建 Coding Editor 组件2.3.2 父组件使用 CodingEditor 组件 2.4 效果展示 三. 总结 &#x1f981; 一. 前言 各位好&#xff01;我是&#x1…

什么是智能运维产品线和服务线

智能运维产品线和服务线涵盖了一系列自动化和智能化的技术和服务&#xff0c;旨在提升IT运维的效率和有效性。智能运维&#xff08;AIOps&#xff09;利用大数据、分析技术和机器学习能力来自动执行和简化运营工作流程&#xff0c;包括收集和汇总多源IT基础架构组件的数据、应用…

1、docker 基础命令

1、docker 运行镜像 docker run image tag 2、创建dockerfile&#xff08;构建容器的相关命令&#xff09; vim DockerFile 3、docker 构建容器镜像 docker build -t <image_name> . 4、docker 分层 5、查看镜像 docker images 6、docker 执行 docker run --name &…

【重要公告】BSV区块链协会全新推出“网络访问规则NAR”

​​发表时间&#xff1a;2024年2月15日 BSV区块链协会正式宣布已为BSV区块链推出一套全新的网络访问规则&#xff08;Network Access Rules&#xff0c;以下简称“NAR”&#xff09;。 NAR是一整套规则&#xff0c;用于规范BSV协会与BSV网络节点之间的关系。它基于比特币最初…

2024年怎么选类目?最容易起店的类目推荐,细分类目蕴含机会

大家好&#xff0c;我是电商花花。 做抖音小店选什么类目一直都是我们新手做店的一个大难题。 类目选对了&#xff0c;对于我们店铺就很容易出单&#xff0c;起店&#xff0c;如果选错了&#xff0c;店铺不出单或者没流量也是一个常见的事情。 而选品选类目本身就没有什么捷…

SikuliX使用介绍

1.SikuliX基本介绍 Sikuli 是 2009 年由 Tsung-Hsiang Chang 和 Tom Yeh在麻省理工学院用户界面设计小组的一个开源研究项目。1 年&#xff0c;两人都离开了 Sikuli-X-0.3rc2012 的项目&#xff0c;RaiMan决定接管开发和支持&#xff0c;并将其命名为 SikuliX。 S…

Pyhton的组合数据类型

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 生命对某些人来说是美丽的&#xff0c…

【MATLAB】MVMD_ MFE_SVM_LSTM 神经网络时序预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 MVMD_MFE_SVM_LSTM神经网络时序预测算法结合了多变量多尺度分解&#xff08;MVMD&#xff09;、多尺度特征提取&#xff08;MFE&#xff09;、支持向量机&#xff08;SVM&#xff09;和长…