【Spring】GoF 之工厂模式

news2024/9/24 20:34:23

一、GoF 23 设计模式简介

  • 设计模式:一种可以被重复利用的解决方案

  • GoF(Gang of Four),中文名——四人组

  • 《Design Patterns: Elements of Reusable Object-Oriented Software》(即《设计模式》一书),1995年由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合著,这几位作者常被称为"四人组(Gang of Four)"

  • 该书中描述了 23 种设计模式,我们平常所说的设计模式就是指这 23 种设计模式

  • 不过除了 GoF23 种设计模式之外,还有其它的设计模式,比如:JavaEE 的设计模式(DAO模式、MVC模式等)

  • GoF23 种设计模式可分为三大类

    • 创建型(5个):解决对象创建问题

      • 单例模式

      • 工厂方法模式

      • 抽象工厂模式

      • 建造者模式

      • 原型模式

    • 结构型(7个):一些类或对象组合在一起的经典结构

      • 代理模式

      • 装饰模式

      • 适配器模式

      • 组合模式

      • 享元模式

      • 外观模式

      • 桥接模式

    • 行为型(11个):解决类或对象之间的交互问题

      • 策略模式

      • 模板方法模式

      • 责任链模式

      • 观察者模式

      • 迭代子模式

      • 命令模式

      • 备忘录模式

      • 状态模式

      • 访问者模式

      • 中介者模式

      • 解释器模式

工厂模式是解决对象创建问题的,所以工厂模式属于创建型设计模式

这里为什么学习工厂模式呢?这是因为 Spring 框架底层使用了大量的工厂模式

 

二、工厂模式的三种形态 

工厂模式通常有三种形态:

  • 第一种:简单工厂模式(Simple Factory):不属于23种设计模式之一,简单工厂模式又叫做:静态 工厂方法模式。简单工厂模式是工厂方法模式的一种特殊实现

  • 第二种:工厂方法模式(Factory Method):是 23 种设计模式之一

  • 第三种:抽象工厂模式(Abstract Factory):是 23 种设计模式之一

 

三、简单工厂模式 

简单工厂模式的角色包括三个:

  • 抽象产品 角色

  • 具体产品 角色

  • 工厂类 角色

简单工厂模式的代码如下:

package org.qiu.simple.factory;

/**
 * 抽象产品角色
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.simple.factory
 * @date 2022-11-09-21:53
 * @since 1.0
 */
public abstract class Weapon {

    /**
     * 所有的武器都可以攻击
     */
    public abstract void attack();
}
package org.qiu.simple.factory;

/**
 * 具体产品角色
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.simple.factory
 * @date 2022-11-09-21:54
 * @since 1.0
 */
public class Tank  extends Weapon{
    @Override
    public void attack() {
        System.out.println("二营长你他娘的意大利炮呢???");
    }
}
package org.qiu.simple.factory;

/**
 * 具体产品角色
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.simple.factory
 * @date 2022-11-09-21:55
 * @since 1.0
 */
public class Fighter extends Weapon{
    @Override
    public void attack() {
        System.out.println("战斗机抛下小男孩!!!");
    }
}
package org.qiu.simple.factory;

/**
 * 具体产品角色
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.simple.factory
 * @date 2022-11-09-21:55
 * @since 1.0
 */
public class Dagger  extends Weapon{
    @Override
    public void attack() {
        System.out.println("砍他丫的!!!");
    }
}
package org.qiu.simple.factory;

/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.simple.factory
 * @date 2022-11-09-21:57
 * @since 1.0
 */
public class WeaponFactory {

    /**
     * 静态方法
     * 要获取什么产品,就看传什么参数
     * 传 TANK 获取坦克
     * 传 DAGGER 获取匕首
     * 传 FIGHTER 获取战斗机
     * @param weaponType
     * @return
     */
    public static Weapon get(String weaponType){
        if ("TANK".equals(weaponType)) {
            return new Tank();
        } else if ("DAGGER".equals(weaponType)) {
            return new Dagger();
        } else if ("FIGHTER".equals(weaponType)){
            return new Fighter();
        } else {
            throw new RuntimeException("暂不支持该武器的生产");
        }
    }
}
public class Test {
    public static void main(String[] args) {
        // 坦克对象
        Weapon tank = WeaponFactory.get("TANK");
        tank.attack();
        // 匕首对象
        Weapon dagger = WeaponFactory.get("DAGGER");
        dagger.attack();
        // 战斗机对象
        Weapon fighter = WeaponFactory.get("FIGHTER");
        fighter.attack();
    }
}

运行结果: 

简单工厂模式的优点:

  • 客户端程序不需要关心对象的创建细节,需要哪个对象时,只需要向工厂索要即可,初步实现了责任的分离,客户端只负责“消费”,工厂负责“生产”,生产和消费分离。

简单工厂模式的缺点:

  • 缺点1:工厂类集中了所有产品的创造逻辑,形成一个无所不知的全能类,有人把它叫做上帝类。显然工厂类非常关键,不能出问题,一旦出问题,整个系统瘫痪

  • 缺点2:不符合 OCP 开闭原则,在进行系统扩展时,需要修改工厂类

Spring 中的 BeanFactory 就使用了简单工厂模式。

 

四、工厂方法模式 

工厂方法模式的角色:

  • 抽象产品角色

  • 具体产品角色

  • 抽象工厂角色

  • 具体工厂角色

/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package PACKAGE_NAME
 * @date 2022-11-10-16:58
 * @since 1.0
 */
public abstract class Weapon {
    public abstract void attack();
}
/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package PACKAGE_NAME
 * @date 2022-11-10-16:58
 * @since 1.0
 */
public class Dagger extends Weapon{
    @Override
    public void attack() {
        System.out.println("刀他丫的!!!");
    }
}
/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package PACKAGE_NAME
 * @date 2022-11-10-16:59
 * @since 1.0
 */
public class Gun extends Weapon{
    @Override
    public void attack() {
        System.out.println("biu~ biu~ biu~");
    }
}
/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package PACKAGE_NAME
 * @date 2022-11-10-17:00
 * @since 1.0
 */
public abstract class WeaponFactory {
    public abstract Weapon get();
}
/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package PACKAGE_NAME
 * @date 2022-11-10-17:01
 * @since 1.0
 */
public class DaggerFactory extends WeaponFactory{
    @Override
    public Weapon get() {
        return new Dagger();
    }
}
/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package PACKAGE_NAME
 * @date 2022-11-10-17:01
 * @since 1.0
 */
public class GunFactory extends WeaponFactory{
    @Override
    public Weapon get() {
        return new Gun();
    }
}
public class Test {
    public static void main(String[] args) {
        WeaponFactory daggerFactory = new DaggerFactory();
        Weapon dagger = daggerFactory.get();
        dagger.attack();
        GunFactory gunFactory = new GunFactory();
        Weapon gun = gunFactory.get();
        gun.attack();
    }
}

运行结果:

厂方法模式的优点:

  • 一个调用者想创建一个对象,只要知道其名称就可以了。

  • 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以

  • 屏蔽产品的具体实现,调用者只关心产品的接口

工厂方法模式的缺点:

  • 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖,这并不是什么好事

 

五、抽象工厂模式(了解即可) 

抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。

抽象工厂模式特点:

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。它有多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,一个抽象工厂类,可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结果。

抽象工厂中包含4个角色:

  • 抽象工厂角色

  • 具体工厂角色

  • 抽象产品角色

  • 具体产品角色

抽象工厂模式的类图如下:

抽象工厂模式的优缺点:

  • 优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象

  • 缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在AbstractFactory里加代码,又要在具体的里面加代码

 

一  叶  知  秋,奥  妙  玄  心

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

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

相关文章

TCP 传输控制协议

1 TCP 1.1 TCP 最主要的特点 1.TCP 是面向连接的运输层协议。 2.每一条 TCP 连接只能有两个端点 (endpoint),每一条 TCP 连接只能是点对点的(一对一)。 3.TCP 提供可靠交付的服务。 4.TCP 提供全双工通信。 5.面向字节流 TCP 中的“流…

【Qt】Android上运行keeps stopping, Desktop上正常

文章目录 问题 & 背景背景问题 解决方案One More ThingTake Away 问题 & 背景 背景 在文章【Qt】最详细教程,如何从零配置Qt Android安卓环境中,我们在Qt中配置了安卓开发环境,并且能够正常运行。 但笔者在成功配置并完成上述文章…

Git、github与gitee码云

1.git核心是两个仓库:本地仓库和远程仓库 主要用于团队合作和代码版本控制(个人现有版本代码出错可回溯上个提交版本的代码) 远程仓库国际主流githut,但外网速度问题,国内可使用码云gitee github:https:…

Springboot拦截器中跨域失效的问题、同一个接口传入参数不同,一个成功,一个有跨域问题、拦截器和@CrossOrigin和@Controller

Springboot拦截器中跨域失效的问题 一、概述 1、具体场景 起因: 同一个接口,传入不同参数进行值的修改时,一个成功,另一个竟然失败,而且是跨域问题拦截器内的request参数调用getHeader方法时,获取不到前端…

CSS:九宫格布局

九宫格布局效果如下&#xff1a; HTML 结构&#xff1a; <div class"container"><div class"item">1</div><div class"item">2</div><div class"item">3</div><div class"item&q…

机器学习系列——(十六)回归模型的评估

引言 在机器学习领域&#xff0c;回归模型是一种预测连续数值输出的重要工具。无论是预测房价、股票价格还是天气温度&#xff0c;回归模型都扮演着不可或缺的角色。然而&#xff0c;构建模型只是第一步&#xff0c;评估模型的性能是确保模型准确性和泛化能力的关键环节。本文…

【力扣】快乐数,哈希集合 + 快慢指针 + 数学

快乐数原题地址 方法一&#xff1a;哈希集合 定义函数 getNext(n) &#xff0c;返回 n 的所有位的平方和。一直执行 ngetNext(n) &#xff0c;最终只有 2 种可能&#xff1a; n 停留在 1 。无限循环且不为 1 。 证明&#xff1a;情况 1 是存在的&#xff0c;如力扣的示例一…

(十八)springboot实战——spring securtity注解方式的授权流程源码解析

前言 在上一节内容中&#xff0c;我们介绍了如何在FilterSecurityInterceptor过滤器中处理用户的授权流程&#xff0c;并分析了其源码&#xff0c;spring security还提供了方法级别的授权方式&#xff0c;通过EnableMethodSecurity注解启用权限认证流程&#xff0c;只需要在方…

每日一题——LeetCode1422.分割字符串的最大得分

方法一 暴力枚举 枚举所有分割点的情况&#xff0c;取最大得分 var maxScore function(s) {let res 0;const n s.length;for (let i 1; i < n; i) {let score 0;for (let j 0; j < i; j) {if (s[j] 0) {score;}}for (let j i; j < n; j) {if (s[j] 1) {sco…

分享86个行业PPT,总有一款适合您

分享86个行业PPT&#xff0c;总有一款适合您 86个行业PPT下载链接&#xff1a;https://pan.baidu.com/s/1avbzwqK8ILLWYIOylK1aRQ?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不易…

TI的电量计驱动在卸载时导致Linux卡死

背景 最近移植TI电量计芯片bq40z50的驱动&#xff0c;移植完毕后&#xff0c;能正常读取电池信息了&#xff0c;但是无意中发现驱动卸载会导致Linux卡死&#xff0c;死前终端闪过大量打印&#xff0c;将putty的缓冲区都耗尽了&#xff0c;必须启用syslog转发并用visual syslog…

【数据结构】链表OJ面试题4(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 后三题在这http://t.csdnimg.cn/gbohQ 给定一个链表&#xff0c;判断链表中是否有环。http://t.csdnimg.cn/Rcdyc 记录每天的刷题&#xff0c;继续坚持&#xff01; 2.OJ题目训练 10. 给定一个链表&#xff0c;返回链表开始…

Qt PCL学习(二):点云读取与保存

注意事项 版本一览&#xff1a;Qt 5.15.2 PCL 1.12.1 VTK 9.1.0前置内容&#xff1a;Qt PCL学习&#xff08;一&#xff09;&#xff1a;环境搭建 0. 效果演示 1. pcl_open_save.pro QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgets// 添加下行代码&#…

外贸邮件群发如何做?外贸邮件群发靠谱吗?

外贸邮件群发有哪些平台&#xff1f;外贸群发邮件用什么邮箱&#xff1f; 外贸邮件群发是许多企业在开展国际贸易时常用的营销手段&#xff0c;它不仅能够快速地将产品信息和促销活动传达给目标客户&#xff0c;还能够有效地建立和维护客户关系。下面&#xff0c;就让蜂邮探讨…

yolov8自制数据训练集

目录 1.YOLOv8是啥 2.系统环境 3.安装labelimg 3.1安装 3.2启动 labelimg 4.自制分类图片 4.1 YOLO数据集要求 4.2 图片保存目录 4.3 利用labelimg进行标注 4.4 存储图片 4.5 标注文件 5.数据集训练 5.1yaml文件 5.2训练命令 5.3查看训练过程 5.3.1启动tensorb…

Python中使用opencv-python库进行颜色检测

Python中使用opencv-python库进行颜色检测 之前写过一篇VC中使用OpenCV进行颜色检测的博文&#xff0c;当然使用opencv-python库也可以实现。 在Python中使用opencv-python库进行颜色检测非常简单&#xff0c;首选读取一张彩色图像&#xff0c;并调用函数imgHSV cv2.cvtColor…

【若依】若依框架在本地运行的操作方法,及踩坑记录

若依框架简介 若依是一个Gitee上一个开源的基于SpringBoot开发的轻量级Java快速开发框架&#xff0c;用以快速构建后台管理系统&#xff0c;点击跳转到官方地址 本机部署过程 Step1. 下载项目源码 我选择的是直接下载zip压缩包&#xff0c;解压后得到如下文件夹&#xff0c…

初识 Protobuf 和 gRpc

初步了解 Protobuf 和 gRpc Protocol Buffers Protocol Buffers&#xff08;又称protobuf&#xff09;是谷歌的语言无关、平台无关、可扩展的机制&#xff0c;用于序列化结构化数据。您可以在protobuf的文档中了解更多关于它的信息。 ProtoBuf 的定义 ProtoBuf是将类的定义…

网神 SecGate 3600 防火墙 route_ispinfo_import_save 文件上传漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

sqli靶场完结篇!!!!

靶场&#xff0c;靶场&#xff0c;一个靶场打一天&#xff0c;又是和waf斗智斗勇的一天&#xff0c;waf我和你拼啦&#xff01;&#xff01; 31.多个)号 先是一套基本的判断 &#xff0c;发现是字符型&#xff0c;然后发现好像他什么都不过滤&#xff1f;于是开始poc 3213131…