工厂模式中简单工厂模式、工厂方法模式、抽象工厂模式的分析与总结

news2024/12/30 1:47:13

工厂模式

工厂模式有许多变体,其中最常见的有三种

  1. 简单工厂模式
  2. 工厂方法模式
  3. 抽象工厂模式

简单工厂代码分析

在这里插入图片描述

UML图中我们可以清晰的看到代码结构 ,首先我们创建一个Car的汽车接口,定制汽车的基本规范,汽车可以的方法是可以跑,所以我们定义了一个抽象的run方法.

  • 定义汽车接口Car
public interface Car {
     void run();

}

接着我们分别定义实现了汽车接口的不同车型

  • 宝马类BMW
public class BMW implements Car{
    @Override
    public void run() {
        System.out.println("宝马正在启动~~");
    }
}
  • 奔驰类Benz
public class Benz implements Car{
    @Override
    public void run() {
        System.out.println("奔驰正在启动~~");
    }
}
  • 比亚迪类BYD
public class BYD implements Car{
    @Override
    public void run() {
        System.out.println("比亚迪启动发现没电了~~");
    }
}
  • 接着我们创建工厂类
public class CarFactory {
    public static Car createCar(String type){
        if ("宝马".equals(type)){
            return new BMW();
        }else if ("奔驰".equals(type)){
            return new Benz();
        }else if ("比亚迪".equals(type)){
            return new BYD();
        }else{
            return null;
        }

    }
}

在上面这个工厂类中,我们通过传入的字符串equals我们要创建的车型是哪一款,匹配上的就创建并返回

  • 编写测试类进行测试
public class Main {
    public static void main(String[] args) {
        //用工厂创建一辆宝马
        Car car1 = CarFactory.createCar("宝马");
        if (car1!=null){
            car1.run();
        }else {
            System.out.println("没有该车型,无法创建!");
        }
        
        //用工厂创建一辆奔驰
        Car car2 = CarFactory.createCar("奔驰");
        if (car2!=null){
            car2.run();
        }else {
            System.out.println("没有该车型,无法创建!");
        }
        
        //用工厂创建一辆宝骏
        Car car3 =CarFactory.createCar("宝骏");
        if (car3!=null){
            car3.run();
        }else {
            System.out.println("没有该车型,无法创建!");
        }
    }
}

运行结果

在这里插入图片描述

为什么工厂模式多种变体呢? 其实每一种变体都有优缺点,没有任何一种设计模式是完美的

对于简单工厂模式来说,他的工厂类是一般是静态的,因此可以直接用类名直接调用工厂方法,来创建实例对象

优点是实现简单,

缺点是缺点是当需要新增产品的时候,要修改工厂类的代码,不符合开闭原则.

工厂方法模式

工厂方法模式代码分析

在这里插入图片描述

在类图中,相比简单工厂模式,我们新增了一个工厂接口,不同的汽车厂商实现了工厂类

汽车接口和各个不同的品牌车代码同上

  • 工厂接口
public interface Factory {
    Car creatCar();
}

我们在接口中声明了一个创建汽车的抽象方法

接下来,我们编写不同的汽车实现类

  • 宝马汽车工厂类BMWFactory
public class BMWFactory implements Factory{

    @Override
    public Car creatCar() {
        return new BMW();
    }
}
  • 奔驰汽车工厂类BenzFactory
public class BenzFactory implements Factory{
    @Override
    public Car creatCar() {
        return new Benz();
    }
}
  • 比亚迪汽车工厂类BYDFactory
public class BYDFactory implements Factory{
    @Override
    public Car creatCar() {
        return new BYD();
    }
}

以上三个类它们都实现了工厂接口

接下类我们编写测试方法,来创建汽车实例,并调用汽车的方法

public class Main {
    public static void main(String[] args) {
        BMWFactory bmwFactory = new BMWFactory();
        Car BMWx5 = bmwFactory.creatCar();
        BMWx5.run();
    }
}

运行结果

在这里插入图片描述

工厂方法模式定义一个抽象工厂接口,该接口中声明了一个用于创建产品的工厂方法,具体的产品类由具体的工厂类来实现。工厂方法模式可以有多个具体的工厂类,每个具体工厂类负责创建一种产品。

优点是符合开闭原则,当需要新增产品时,只需要新增具体的产品类和对应的具体工厂类即可,不需要修改抽象工厂接口和抽象工厂类的代码。

缺点是增加了系统的复杂程度

抽象工厂模式

为了方便包管理,我们将包进行了分类,如下

在这里插入图片描述

新增了一个包Logos,在该包中定义了一个名字叫做Logos的接口

  • Logos接口
public interface Logos {
    void showLogos();
}

我们可以看到,这个接口的接口方法是用于创建车标的,接下类每一个实现它的类,都要重写这个接口方法

  • BMWLogos类 (Logos的实现类,用于创建宝马车标)
public class BMWLogos implements Logos{
    @Override
    public void showLogos() {
        System.out.println("我的LOGO是宝马");
    }
}
  • BenzLogos类 (Logos的实现类,用于创建奔驰车标)
public class BuziLogos implements Logos{
    @Override
    public void showLogos() {
        System.out.println("我的LOGO是奔驰~");
    }
}
  • BYDLogos类 (Logos的实现类,用于创建BYD车标)
public class BYDLogos implements Logos{
    @Override
    public void showLogos() {
        System.out.println("我的LOGO是 比亚迪");
    }
}

接着我们创建工厂接口

  • 工厂接口Factory
public interface Factory {
    Car createCar();
    Logos createLogos();
}

这个接口中,我们声明了两个接口方法,一个用于创建车辆,一个用于创建车标,接下来每一个实现工厂的接口都要进行重写这两个方法

  • 宝马族工厂类 BMWFamilyFactory
public class BMWFamilyFactory implements Factory {
    @Override
    public Car createCar() {
        return new BMW();
    }

    @Override
    public Logos createLogos() {
        return new BMWLogos();
    }
}
  • 奔驰族工厂类 BenzFamilyFactory
public class BenzFamilyFactory implements Factory{
    @Override
    public Car createCar() {
        return new Benz();
    }

    @Override
    public Logos createLogos() {
        return new BuziLogos();
    }
}
  • 比亚迪族工厂类 BYDFamilyFactory
public class BYDFamilyFactory implements Factory{
    @Override
    public Car createCar() {
        return new BYD();
    }

    @Override
    public Logos createLogos() {
        return new BYDLogos();
    }
}

细心的你会发现,相比于上面的工厂方法模式,这里的工厂实现类名字都会多一个Family,为什么呢?

因为抽象工厂方法模式是用来创建产品的一系列实例的,每个具体工厂类只能创建属于自己产品族的产品对象,不同产品族的产品对象不能混淆。

  • 测试类
public class Main {
    public static void main(String[] args) {
        //创建奔驰工厂
        Factory benzFamilyFactory = new BenzFamilyFactory();
        benzFamilyFactory.createCar().run();//创建一辆奔驰并且使用run方法
        benzFamilyFactory.createLogos().showLogos();


        BMWFamilyFactory bmwFamilyFactory = new BMWFamilyFactory();
        bmwFamilyFactory.createCar().run();//创建一辆奔驰并且使用run方法
        bmwFamilyFactory.createLogos().showLogos();//创建一辆奔驰LOGO并且显示LOGO

    }
}

运行结果

在这里插入图片描述

抽象工厂模式的优点在于,它能够保证创建的产品对象之间的兼容性。因为每个具体工厂类只能创建属于自己产品族的产品对象,所以不同产品族之间的产品对象不会产生冲突。此外,抽象工厂模式还支持增加新的产品族,而不需要修改已有的代码,符合开闭原则。但是,抽象工厂模式也有一些缺点。由于抽象工厂接口需要定义一组用于创建不同产品族的方法,因此当新增加一个产品族时,需要修改抽象工厂接口及其所有实现类,这可能会导致一定的代码修改工作量。

总结

简单工厂模式:

​ 由一个工厂类根据传入的参数决定创建哪种产品类的实例。简单工厂模式将对象的创建和使用分离开来,客户端只需要传入参数,就可以得到所需的对象,无需关心对象的创建细节。

工厂方法模式:

​ 定义一个创建产品对象的接口,由子类决定实例化哪一个产品类。工厂方法模式将对象的创建延迟到子类中去实现,客户端只需要知道所需产品的工厂类即可,无需关心具体的产品类。

抽象工厂模式:

​ 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式可以看作是工厂方法模式的升级版,它支持创建一组相关的产品对象。抽象工厂模式能够保证创建的产品对象之间的兼容性,但是新增加一个产品族时需要修改抽象工厂接口及其所有实现类。

简单工厂模式:

优点:

  1. 工厂类中包含了必要的逻辑判断,可以根据客户端的请求动态地创建相关的产品对象,客户端无需知道具体的产品类。
  2. 简单工厂模式将对象的创建和使用分离开来,客户端只需要关心所需产品的参数,无需关心对象的创建细节。

缺点:

  1. 简单工厂模式工厂类职责过重,增加新的产品需要修改工厂类的判断逻辑,违背了开闭原则。
  2. 简单工厂模式只支持一种产品族的创建,不支持扩展。

工厂方法模式:

优点:

  1. 工厂方法模式将对象的创建延迟到子类中去实现,符合开闭原则,新增加产品时只需要添加对应的工厂类即可。
  2. 工厂方法模式支持扩展,可以创建多个产品族的对象。

缺点:

  1. 工厂方法模式需要新增加相应的工厂类,增加了代码的复杂度。
  2. 工厂方法模式增加了系统的抽象性和理解难度。

抽象工厂模式:

优点:

  1. 抽象工厂模式能够保证创建的产品对象之间的兼容性,因为每个具体工厂类只能创建属于自己产品族的产品对象,不同产品族的产品对象不能混淆。
  2. 抽象工厂模式支持增加新的产品族,而不需要修改已有的代码,符合开闭原则。

缺点:

  1. 抽象工厂模式需要新增加相应的接口及实现类,增加了代码的复杂度。
    单工厂模式只支持一种产品族的创建,不支持扩展。

工厂方法模式:

优点:

  1. 工厂方法模式将对象的创建延迟到子类中去实现,符合开闭原则,新增加产品时只需要添加对应的工厂类即可。
  2. 工厂方法模式支持扩展,可以创建多个产品族的对象。

缺点:

  1. 工厂方法模式需要新增加相应的工厂类,增加了代码的复杂度。
  2. 工厂方法模式增加了系统的抽象性和理解难度。

抽象工厂模式:

优点:

  1. 抽象工厂模式能够保证创建的产品对象之间的兼容性,因为每个具体工厂类只能创建属于自己产品族的产品对象,不同产品族的产品对象不能混淆。
  2. 抽象工厂模式支持增加新的产品族,而不需要修改已有的代码,符合开闭原则。

缺点:

  1. 抽象工厂模式需要新增加相应的接口及实现类,增加了代码的复杂度。
  2. 抽象工厂模式增加了系统的抽象性和理解难度。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【sed编辑器】

目录 一、sed编辑器二、sed的命令格式操作命令1.1、命令演示 二、替换三、插入 一、sed编辑器 1、sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 2、sed编辑器可以根据命令来处理数据流中的数据,这些命令要么…

OSC Liblo Window10配置

OpenSoundControl一种网络通讯协议,想了解详情的自行打开网站。 liblo 是最知名的OSC库, 功能完整,用 C 和 LGPL 许可编写。 下载请前往GitHub库。 解压后安装过程如下,需要用到CMake: 1.选择源代码文件和构建工程的文…

一文读懂“生成式 AI”

一、前言 本文基于谷歌的:《Introduction to Generative AI》 并且借助 ChatGPT 整理而成,帮助大家理解生成式 AI 这个概念。 主要包括 4 个部分: 生成式 AI 的定义生成式 AI 的工作原理生成式 AI 模型的分类生成式 AI 的应用 二、生成式…

【数据结构】双向带头循环链表的实现

目录 全部代码 图例(双向带头循环链表) 各个功能的实现 创建该链表的节点 创建初始链表 链表的头插 链表的尾插 链表的随机插入 链表的头删 链表的尾删 链表的随机删除 链表的销毁 链表是否为空的判断 链表节点的创建 总结 全部代码 typ…

命令行更新Windows

命令行更新Windows powershell命令行更新安装 Windows Update module for Windows Powershell连接到 Windows Update 服务器并下载更新安装下载好的 Windows Update 更新 cmd执行Windows update更新检查更新下载 Windows Update 更新安装更新安装更新后重新启动设备 win10以下版…

Python中Pandas库的相关操作

目录 Pandas库 常用操作 创建DataFrame 查看数据 数据选择和过滤 数据排序和排名 缺失数据处理 数据聚合和分组 数据的合并和连接 Pandas库 Pandas是Python中常用的数据处理和分析库,它提供了高效、灵活且易于使用的数据结构和数据分析工具。 1.Series&a…

实例35---字符串反转,如将字符串 “www.runoob.com“ 反转为 “moc.boonur.www“。

文章目录 前言一、题目描述 二、题目分析 三、解题 1.解题方法一--- for循环来将字符的下标数值进行对每一个字符进行交换 ---程序运行代码 2.解题方法二------ 指针 ------ 程序运行代码(1)程序运行代码优化 总结 前言 本系列为C语言菜鸟100道基础经典例题详解刷题系列。点滴…

微服务:服务发现

1. 服务发现 eureka、nacos、Consul、etcd 和 zk 都是主流的服务发现工具,而 Dubbo 和 Polaris Mesh 则是基于服务发现的 RPC 框架。 它们的主要区别在于: eureka 是 Netflix 开源的一个服务发现组件,支持高可用和数据同步,具有…

如何使用Linkage Mapper揭示栖息地变化的故事

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Linkage Mapper解密数字世界链接 文章目录 引言1.1 定义和作用1.2 Linkage Mapper的历史和发展2.1 揭示栖息地变化的重要性2.2 Linkage Mapper的优势和不足

Windows下载安装RocketMq

Windows下载安装RocketMq 下载安装包启动NAMESERVER 和 BROKER启动NAMESERVER启动BROKER 安装可视化插件 下载安装包 RockitMQ官网下载地址:https://rocketmq.apache.org/release-notes/ 解压到指定的文件夹下 先配置JAVA_HOME 配置ROCKETMQ_HOME环境变量 …

使用Maple的Python API :OpenMaple(Windows下的解决方案)

在Maple 2023(按照软件文档,Maple 2018及以上版本均适用;我目前测试的版本为2023)的安装目录下,有软件附带的解释器,如D:\Program Files\Maple 2023\Python.X86_64_WINDOWS\Python.exe。这一Python解释器的…

Python中NumPy库的相关操作

目录 NumPy库 常用操作 创建数组 数组属性 索引和切片 数组运算 数组重塑 NumPy库 NumPy(Numerical Python)是Python中常用的数值计算库,它提供了高性能的多维数组对象和对数组进行操作的函数。 1.多维数组对象(ndarray&…

Java 课程设计 —— 扫雷

一、团队课程设计博客链接: https://www.cnblogs.com/luomeili/p/10280310.html 二、个人负责模块或任务说明: 模块:文件操作 Minefield 类实现 三、自己的代码提交记录截图 四、自己负责模块或任务详细说明 1.Minefield 类实现 Minefie…

Java中的CountDownLatch和CyclicBarrier有什么作用?

在Java并发编程中,CountDownLatch和CyclicBarrier是两个非常有用的工具,它们可以帮助我们更加方便地进行线程通信和协作。在本文中,我将从面试的角度,详细讲解Java中的CountDownLatch和CyclicBarrier的概念、作用和实现方式&#…

基于卷积的图像分类识别(六):DenseNet FractalNet

系列文章目录 本专栏介绍基于深度学习进行图像识别的经典和前沿模型,将持续更新,包括不仅限于:AlexNet, ZFNet,VGG,GoogLeNet,ResNet,DenseNet,SENet,MobileN…

如何搭建自己的git服务器

GitHub,Gitee 想来大家都用过,我们的代码就是托管在这些平台上的。因此,你可能好奇为什么我们不自己搭建一个 git 呢服务器?下面,就开始教大家如何一步步搭建自己的 git 服务器(试验成功的那一刻还是很让人…

Java 中 ArrayList 和 LinkedList 有什么区别

在Java中,ArrayList和LinkedList是两种常见的集合类。它们都实现了List接口,提供了类似数组的功能,可以存储任意类型的对象。虽然它们都可以实现相同的功能,但是它们的底层实现方式有所不同,因此在性能和用途上也存在一…

dom4j解析XML文件

主要为了讲解Mybatis中如何用dom4j解析XML,这里当作dom4j解析.XML文件的练习 引入mybatis配置文件和一个.xml文件 都是.xml <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN…

【C++】| 04——STL | 容器_vector

系列文章目录 【C】| 01——泛型编程 | 模板 【C】| 02——STL | 初识 【C】| 03——STL | 迭代器 【C】| 04——STL | 容器_vector 文章目录 1. vector容器2. vector库2.1 迭代器相关函数2.1 ww 1. vector容器 vector 与 动态数组 相似&#xff0c;可以自动调节自身大小。元素…

基于SpringBoot的美容院管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SpringBoot 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录 一、项目简介 二、系…