当前位置: 首页 > news >正文

01-Spring中的工厂模式

工厂模式

工厂模式的三种形态: 工厂模式是解决对象创建问题的属于创建型设计模式,Spring框架底层使用了大量的工厂模式

  • 第一种:简单工厂模式是工厂方法模式的一种特殊实现,简单工厂模式又叫静态工厂方法模式不属于23种设计模式之一
  • 第二种:工厂方法模式, 是23种设计模式之一
  • 第三种:抽象工厂模式, 是23种设计模式之一

简单/静态工厂模式

简单工厂模式的优点

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

简单工厂模式的缺点

  • 工厂类集中了所有产品的创造逻辑,有人把它叫做上帝类/全能类, 显然工厂类非常关键一旦出问题整个系统将瘫痪
  • 不符合OCP开闭原则,在进行系统产品扩展时需要修改工厂类的代码创建新的产品,这样客户端才能获取到扩展的产品

简单工厂模式的角色包括三个:抽象产品角色,具体产品角色, (静态)工厂类角色(提供创建对象的静态方法)

// 抽象产品角色: 武器
public abstract class Weapon {// 所有的武器都有攻击行为public abstract void attack();
}
// 具体产品角色:坦克
public class Tank extends Weapon{@Overridepublic void attack() {System.out.println("坦克开炮!");}
}
// 具体产品角色:战斗机
public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机投下原子弹!");}
}
//工厂类角色:根据不同的武器类型不同的生产武器
public class WeaponFactory {// 根据不同的武器类型生产不同的武器public static Weapon get(String weaponType){if (weaponType == null || weaponType.trim().length() == 0) {return null;}Weapon weapon = null;if ("TANK".equals(weaponType)) {weapon = new Tank();} else if ("FIGHTER".equals(weaponType)) {weapon = new Fighter();} else {throw new RuntimeException("不支持该武器!");}return weapon;}
}

编写测试程序,通过指定武器的类型从静态工厂中获取对应的武器

public class Client {public static void main(String[] args) {Weapon weapon1 = WeaponFactory.get("TANK");weapon1.attack();Weapon weapon2 = WeaponFactory.get("FIGHTER");weapon2.attack();}
}

工厂方法模式

工厂方法模式既保留了简单工厂模式的优点,同时又解决了简单工厂模式的缺点

  • 客户端程序不需要关心对象的创建细节,需要哪个对象时只需要向对应的工厂索要即可, 客户端只负责消费,工厂只负责生产
  • 如果想进行产品扩展,只需要添加一个具体产品类和一个具体工厂类,不需要修改原来的代码符合OCP原则

工厂方法模式的缺点

  • 每次增加一个产品时都需要增加一个具体类和对象实现工厂, 使得系统中类的个数成倍增加导致系统的复杂度增加,同时也增加了系统具体类的依赖

工厂方法模式的角色包括:抽象工厂角色(生产多种武器), 具体工厂角色(一个工厂对应生产一种武器), 抽象产品角色, 具体产品角色

//抽象工厂角色: 专门生产各种武器的工厂
public interface WeaponFactory {Weapon get();
}
//具体工厂角色:专门生产枪的工厂
public class GunFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Gun();}}
//具体工厂角色:专门生成飞机的工厂(工厂也可以通过简单工厂模式封装成一个大工厂,然后调用其的静态方法创建对应的工厂)
public class FighterFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Fighter();}
}
// 抽象产品角色: 武器类
public abstract class Weapon {// 所有武器都有攻击行为public abstract void attack();
}
// 具体产品角色:枪
public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");}
}
// 具体产品角色:战斗机
public class Fighter extends Weapon{@Overridepublic void attack() {System.out.println("战斗机发射核弹!");}
}

编写测试程序,获取对应的工厂创建对应的产品

public class Client {public static void main(String[] args) {// 这里的new GunFactory()可以采用简单工厂模式进行隐藏,调用WeaponFactory的静态方法根据传递的参数创建对应的工厂WeaponFactory factory = new GunFactory();Weapon weapon = factory.get();weapon.attack();WeaponFactory factory1 = new FighterFactory();Weapon weapon1 = factory1.get();weapon1.attack();}
}

新增一个匕首产品类只需要新增一个该产品对应的匕首工厂即可

// 具体产品角色:匕首
public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("切割!");}
}
//具体工厂角色:专门生产匕首的工厂
public class DaggerFactory implements WeaponFactory{@Overridepublic Weapon get() {return new Dagger();}
}
// 测试生产新增的产品类
public class Client {public static void main(String[] args) {WeaponFactory factory2 = new DaggerFactory();Weapon weapon2 = factory2.get();weapon2.attack();}
}

抽象工厂模式

工厂方法模式是针对一个产品等级结构(一个产品系列一个工厂类),而抽象工厂模式是针对多个产品等级结构(多个产品系列一个工厂类)

抽象工厂模式的优点

  • 可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象
  • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
  • 一个抽象工厂类可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例

抽象工厂模式缺点

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

在这里插入图片描述

抽象工厂中包含4个角色:抽象工厂角色, 具体工厂角色, 抽象产品角色, 具体产品角色

抽象产品角色:武器产品族,水果产品族

public abstract class Weapon {// 所以武器都有攻击行为public abstract void attack();
}public abstract class Fruit {// 所有果实都有一个成熟周期public abstract void ripeCycle();
}

具体产品角色:武器产品族

// 武器产品族中的产品等级1
public class Gun extends Weapon{@Overridepublic void attack() {System.out.println("开枪射击!");}
}// 武器产品族中的产品等级2
public class Dagger extends Weapon{@Overridepublic void attack() {System.out.println("切割!");}
}// 水果产品族中的产品等级1
public class Orange extends Fruit{@Overridepublic void ripeCycle() {System.out.println("橘子的成熟周期是10个月");}
}package com.powernode.product;// 水果产品族中的产品等级2 
public class Apple extends Fruit{@Overridepublic void ripeCycle() {System.out.println("苹果的成熟周期是8个月");}
}

抽象工厂角色: 既能生产武器又能生产水果

public abstract class AbstractFactory {public abstract Weapon getWeapon(String type);public abstract Fruit getFruit(String type);
}

具体工厂角色: 武器族工厂, 水果族工厂,根据用户提供的名称创建具体的产品

// 武器族工厂
public class WeaponFactory extends AbstractFactory{public Weapon getWeapon(String type){if (type == null || type.trim().length() == 0) {return null;}if ("Gun".equals(type)) {return new Gun();} else if ("Dagger".equals(type)) {return new Dagger();} else {throw new RuntimeException("无法生产该武器");}}@Overridepublic Fruit getFruit(String type) {return null;}
}
// 水果族工厂
public class FruitFactory extends AbstractFactory{@Overridepublic Weapon getWeapon(String type) {return null;}public Fruit getFruit(String type){if (type == null || type.trim().length() == 0) {return null;}if ("Orange".equals(type)) {return new Orange();} else if ("Apple".equals(type)) {return new Apple();} else {throw new RuntimeException("我家果园不产这种水果");}}
}

测试程序

public class Client {public static void main(String[] args) {// 客户端调用方法时只面向AbstractFactory调用方法AbstractFactory factory = new WeaponFactory(); Weapon gun = factory.getWeapon("Gun");Weapon dagger = factory.getWeapon("Dagger");gun.attack();dagger.attack();AbstractFactory factory1 = new FruitFactory(); Fruit orange = factory1.getFruit("Orange");Fruit apple = factory1.getFruit("Apple");orange.ripeCycle();apple.ripeCycle();}
}

相关文章:

01-Spring中的工厂模式

工厂模式 工厂模式的三种形态: 工厂模式是解决对象创建问题的属于创建型设计模式,Spring框架底层使用了大量的工厂模式 第一种:简单工厂模式是工厂方法模式的一种特殊实现,简单工厂模式又叫静态工厂方法模式不属于23种设计模式之一第二种:工厂方法模式…...

Linux是什么,Linux系统介绍

很多小伙伴都不是那么了解和知道Linux,到底Linux是什么? 像大家用到的安卓手机,生活中用到的各种智能设备,比如路由器,光猫,智能家具等,很多都是在Linux操作系统上。 Linux是什么?Li…...

爬虫项目(11):使用多线程对36手机高清壁纸批量抓取

文章目录 书籍推荐目标网址单线程实现多线程实现爬取结果书籍推荐 如果你对Python网络爬虫感兴趣,强烈推荐你阅读《Python网络爬虫入门到实战》。这本书详细介绍了Python网络爬虫的基础知识和高级技巧,是每位爬虫开发者的必读之作。详细介绍见👉: 《Python网络爬虫入门到…...

JavaScript_动态表格_删除功能

1、动态表格_删除功能 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>动态表格_添加和删除功能</title><style>table{border: 1px solid;margin: auto;width: 100%;}td,th{text-align: …...

一步一步开发微信小程序(Django+Mysql)

前提&#xff1a;假设你已经安装好Anaconda&#xff0c;微信开发者工具&#xff0c;MySQL数据库&#xff0c;IDE等工具 工具下载地址&#xff1a; Anaconda&#xff1a;https://www.anaconda.com/download MySQL&#xff1a;https://dev.mysql.com/downloads/mysql/ 微信开…...

mysql 讲解(1)

文章目录 前言一、基本的命令行操作二、操作数据库语句2.1、创建数据库2.2、删除数据库2.3、使用数据库2.4 查看所有数据库 三、列的数据类型3.1 字符串3.2 数值3.3 时间日期3.4 空3.5 int 和 varchar问题总结&#xff1a; 四、字段属性4.1 UnSigned4.2 ZEROFILL4.3 Auto_InCre…...

k8s关于metadata、spec.containers、spec.volumes的属性介绍(yaml格式)

目录 一.metadata常用属性 二.spec.containers子属性介绍 explain pod.spec.containers给出的参考 1.command示例演示 2.env和envFrom示例演示 3.ports部分详解 4.resources部分详解 5.startupProbe格式演示 6.terminationMessagePath和terminationMessagePolicy格式演…...

腾讯域名优惠卷领取

腾讯域名到到期了&#xff0c;听说申请此计划&#xff0c;可获得优惠卷&#xff0c;看到网上5年域名只需要10元&#xff0c;姑且试试看。 我的博客即将同步至腾讯云开发者社区&#xff0c;邀请大家一同入驻&#xff1a;https://cloud.tencent.com/developer/support-plan?in…...

elastic-job 完结篇

一 elastic-job 1.1 案例场景分析 1.设置4个分片&#xff0c;10秒执行一次。 分片弹性扩容缩容机制测试&#xff1a; 测试1&#xff1a;测试窗口1不关闭&#xff0c;再次运行main方法查看控制台日志&#xff0c;注意修改application.properties中的 server.port&#xf…...

基于 Gin 的 HTTP 代理 demo

上次用 TCP 模拟了一个 HTTP 代理之后&#xff0c;感觉那样还是太简陋了&#xff0c;想着是不是可以用框架来做一个有点实际用处的东西。所以&#xff0c;就思索如何用 golang 的 Gin 框架来实现一个&#xff1f;嗯&#xff0c;对的你没有听错&#xff0c;是 gin 框架。你可能会…...

【ATTCK】MITRE Caldera - 测试数据泄露技巧

CALDERA是一个由python语言编写的红蓝对抗工具&#xff08;攻击模拟工具&#xff09;。它是MITRE公司发起的一个研究项目&#xff0c;该工具的攻击流程是建立在ATT&CK攻击行为模型和知识库之上的&#xff0c;能够较真实地APT攻击行为模式。 通过CALDERA工具&#xff0c;安全…...

【数据结构】树与二叉树(十二):二叉树的递归创建(算法CBT)

文章目录 5.2.1 二叉树二叉树性质引理5.1&#xff1a;二叉树中层数为i的结点至多有 2 i 2^i 2i个&#xff0c;其中 i ≥ 0 i \geq 0 i≥0。引理5.2&#xff1a;高度为k的二叉树中至多有 2 k 1 − 1 2^{k1}-1 2k1−1个结点&#xff0c;其中 k ≥ 0 k \geq 0 k≥0。引理5.3&…...

Qt绘制网格和曲线

绘制网格&#xff1a; void Widget::drawGrid(QPainter &p, QRect &windRect) {QRect rect(windRect.left()m_margins.left(),windRect.top()m_margins.top(),windRect.width()-m_margins.left()-m_margins.right(),windRect.height()-m_margins.top()-m_margins.bo…...

2023-11-12

今日比较摆烂, 但是把自写管道的原理搞懂了, 主要是把 exp 完完全全看懂了, 还不错. 然后就没干啥了. 明日计划: 学校的作业. AFL 源码. 我真是服了我自己了, AFL 源码搁多久了, 操操操 然后把 seccomp 重新学习下...

[工业自动化-16]:西门子S7-15xxx编程 - 软件编程 - 西门子仿真软件PLCSIM

目录 前言&#xff1a; 一、PLCSIM仿真软件 1.1 PLCSIM仿真软件基础版&#xff08;内嵌&#xff09; 1.2 PLCSIM仿真软件与PLCSIM仿真软件高级版的区别&#xff1f; 1.3 PLCSIM使用 前言&#xff1a; PLC集成开发环境是运行在Host主机上&#xff0c;Host主机与PLC可以通过…...

运行npm install卡住不动的几种解决方案

在前端开发经常会遇到运行npm install 来安装工具包一直卡住不动&#xff0c;为此这里提供几种解决方案&#xff0c;供大家参考学习&#xff0c;不足之处还请指正。 第一种方案、首先检查npm代理&#xff0c;是否已经使用国内镜像 // 执行以下命令查看是否为国内镜像 npm con…...

[Android]_[初级]_[配置gradle的环境变量设置安装位置]

场景 在开发Android项目的时候, gradle是官方指定的构建工具。不同项目通过wrapper指定不同版本的gradle。随着项目越来越多&#xff0c;使用的gradle版本也增多&#xff0c;导致它以来的各种库也增加&#xff0c;系统盘空间不足&#xff0c;怎么解决&#xff1f; 说明 grad…...

docker更改存储目录原因及方案

为什么一定要将docker的存储目录挂载到其他目录 docker在安装时默认存储目录在/var/lib/docker&#xff0c;而该目录是在系统盘下的。docker安装后&#xff0c;会使用各种各样的镜像&#xff0c;动辄几个G&#xff0c;那么如此多的镜像文件&#xff0c;装着装着系统盘就撑爆了…...

HTTPS的工作流程

. HTTPS是什么&#xff1f; https是应用层中的一个协议&#xff0c;是在http协议的基础上引入的一个加密层。 为什么需要HTTPS 由于http协议内容都是按照文本的方式明文传输的&#xff0c;这就导致传输过程中会出现一些被篡改的情况。运营商劫持事件最开始百度&#xff0c;…...

C++语言的广泛应用领域

目录 1. 系统级编程 2. 游戏开发 3. 嵌入式系统 4. 大数据处理 5. 金融和量化分析 6. 人工智能和机器学习 7. 网络和通信 结语 C是一种多范式编程语言&#xff0c;具有高性能、中级抽象能力和面向对象的特性。由Bjarne Stroustrup于1979年首次设计并实现&#xff0c;C在…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

2.3 物理层设备

在这个视频中&#xff0c;我们要学习工作在物理层的两种网络设备&#xff0c;分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间&#xff0c;需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质&#xff0c;假设A节点要给…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...