【Spring】GoF 之工厂模式

一、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{@Overridepublic 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{@Overridepublic 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{@Overridepublic 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{@Overridepublic 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{@Overridepublic 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{@Overridepublic 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{@Overridepublic 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.mzph.cn/news/676043.shtml

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

相关文章

MySQL 的Sql脚本是如何被编译的

MySQL是一个关系型数据库管理系统(RDBMS),它使用SQL(Structured Query Language,结构化查询语言)作为其主要的查询语言。在MySQL中运行一个SQL脚本时,MySQL实际上并不会像传统的编程语言那样将S…

企业级人脸属性检测解决方案

在当今数字化、智能化的时代背景下,人脸识别技术已经成为众多行业不可或缺的一部分。美摄科技,作为人脸识别技术的领先者,为企业提供了一整套先进且高效的人脸属性检测解决方案。 美摄科技的人脸属性检测解决方案,基于深度学习算…

使用深度学习对网络摄像头图像进行分类

目录 加载相机和预训练网络 对相机快照进行分类 连续对相机图像进行分类 显示排名靠前的预测值 连续分类图像并显示排名靠前的预测值 另请参阅 此示例说明如何使用预训练的深度卷积神经网络 GoogLeNet 实时对来自网络摄像头的图像进行分类。 使用 MATLAB、普通的…

Vue-Vue3 集成编辑器功能

1、安装依赖 编辑器插件需要安装 wangeditor/editor 和 wangeditor/editor-for-vue 两个插件 npm install wangeditor/editor --savevue3运行如下命令安装 npm install wangeditor/editor-for-vuenext --savevue2运行如下命令安装 npm install wangeditor/editor-for-vue -…

Java强训day15(选择题编程题)

选择题 自连接使用一张表编程题 题目1 import java.util.Scanner;public class Main { public static int res(int n) {StringBuffer s new StringBuffer();while(n!0) {s.append(n%2);n/2;}int sum 0;String ss s.reverse().toString();for(int i0;i<ss.length()…

C语言的循环结构

目录 前言 1.三种循环语句 1.while循环 2.for循环 2.1缺少表达式的情况 3.do while循环 2.break语句和continue语句 2.1在while循环中 2.2在for循环中 2.3在do while 循环中 3.循环的嵌套 4.go to语句 前言 C语⾔是结构化的程序设计语⾔&#xff0c;这⾥的结构指的是…

LeetCode 207:课程表(图论,利用拓扑排序判断是否有环)

题目 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学习课程 ai 则 必须 先学习课程 bi 。 …

nginx + DNS域名解析

配置链接: Nginx 安装配置 | 菜鸟教程 安装完nginx后&#xff0c;访问&#xff1a; cd /usr/local/nginx/sbin/ 然后使用./nginx可使用nginx。 访问:http://服务器的ip地址后出现 因为访问IP地址很繁琐&#xff0c;需要记忆ip的数字地址&#xff0c;因此需要给它一个通俗的…

Rust入门2——随机数

文章目录 一、生成随机数二、比较两个数相等 简单列出两个Rust的小例子 一、生成随机数 在Cargo.toml的dependencies中引入rand&#xff0c;指定rand的版本 [dependencies] rand "^0.3.14"之后在主函数中调用rand函数&#xff0c;生成随机数 use rand::Rng; f…

MyBatis 实现动态 SQL

MyBatis 中的动态 SQL 就是SQL语句可以根据不同的情况情况来拼接不同的sql。 本文会介绍 xml 和 注解 两种方式的动态SQL实现方式。 XML的实现方式 先创建一个数据表&#xff0c;SQL代码如下&#xff1a; DROP TABLE IF EXISTS userinfo; CREATE TABLE userinfo (id int(1…

Mac上几款好用的MacBook视频播放器

使用Mac电脑时&#xff0c;视频播放器可以说是我们使用频率最高的软件之一了&#xff0c;不管是工作时看视频资料还是在家里看下载好的电影&#xff0c;都需要用到视频播放器&#xff0c;本文中我们就来推荐几款好用的Macbook视频播放器&#xff0c;总有一款适合你&#xff01;…

centos ssh 默认端口 修改

centos7更改SSH端口-腾讯云开发者社区-腾讯云 (tencent.com) linux centos修改ssh端口号_semanage port -a -t ssh_port_t -p tcp-CSDN博客

数据结构——B/顺序表和链表

&#x1f308;个人主页&#xff1a;慢了半拍 &#x1f525; 创作专栏&#xff1a;《史上最强算法分析》 | 《无味生》 |《史上最强C语言讲解》 | 《史上最强C练习解析》 &#x1f3c6;我的格言&#xff1a;一切只是时间问题。 ​ 1.线性表 线性表&#xff08;linear list&…

QXlsx Qt操作excel(1)

QXlsx 是一个用于处理Excel文件的开源C库。它允许你在你的C应用程序中读取和写入Microsoft Excel文件&#xff08;.xlsx格式&#xff09;。该库支持多种操作&#xff0c;包括创建新的工作簿、读取和写入单元格数据、格式化单元格、以及其他与Excel文件相关的功能。 关于QXlsx的…

SQL拆分字段内容(含分隔符)

问题描述&#xff1a; 在做数据迁移的过程中&#xff0c;我们希望对表中的某个字段根据分隔符进行拆分&#xff0c;得到多条数据&#xff0c;原代码有点意思&#xff0c;因此记录一下。 我们假设某条数据如下&#xff1a; IDSTRS1公司名称不能小于四个字&#xff0c;行业类别…

【OrangePi Zero2的系统移植】OrangePi Zero2 SDK说明

一、使用环境要求 二、获取Linux SDK 三、首次编译完整SDK 基于OrangePi Zero2的系统移植 之前我们讲解香橙派的使用时&#xff0c; 都是直接在香橙派上进行代码编译&#xff0c; 但在实际的项目开发过程中&#xff0c;更多 的还是使用交叉编译环境进行代码的编译。再编译完成…

卷积层Conv1d包含的元素分别是什么,经过卷积层,数据的形状发生变化吗?

nn.Conv1d 是一个一维卷积层&#xff0c;它通常用于处理序列数据&#xff0c;如时间序列或文本数据。这个层包含以下主要元素&#xff1a; 输入通道数&#xff08;In_channels&#xff09;&#xff1a;这是输入数据的通道数。对于单通道数据&#xff08;如灰度图像或单变量时间…

医学三基答案在哪搜?4个大学生必备的搜题 #知识分享#职场发展

今天&#xff0c;我将分享一些受欢迎的、被大学生广泛使用的日常学习工具&#xff0c;希望能给你的学习生活带来一些便利和启发。 1.颐博咨询 这是一个网站 找题好用的在线搜题站,快考不限次搜题助手,问题截图搜题软件,练题通关考试试题大全。 2.题小聪 这是一个公众号 这…

macbookair怎么清理内存 ?如何利用 CleanMyMac X 进行系统清理

macbookair怎么清理内存 清理MacBook Air的内存可以通过以下几种方法&#xff1a; 优化储存空间。在MacBook Air上&#xff0c;可以通过“优化储存空间”来释放空间。这包括将文件储存在iCloud中&#xff0c;如桌面、文稿和iCloud信息&#xff0c;以及自动移除在iCloud中观看…

QT时间日期与定时器

时间日期与定时器 QTime: 时间数据类型&#xff0c;仅表示时间&#xff0c;如 15&#xff1a;23&#xff1a;13 QDate: 日期数据类型&#xff0c;仅表示日期&#xff0c;如 2017-4-5 QDateTime: 表示日期时间 如 2017-03-23 08&#xff1a;12&#xff1a;43 【示例】&#xf…