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

【2023-05-09】 设计模式(单例,工厂)

2023-05-09 设计模式(单例,工厂)

单例模式

顾名思义,就是整个系统对外提供的实例有且只有一个

特点:

​ 1、单例类只有一个实例

​ 2、必须是自己创建唯一实例

​ 3、必须给所以对象提供这个实例

分类:一般分为饿汉式单例(直接实例化)和懒汉式单例(使用时才实例化)

饿汉式单例

public class SingletonTest {//构造器私有化,防止外部调用private SingletonTest() {}//直接实例化private static SingletonTest sin = new SingletonTest();public static SingletonTest getInstance(){return sin;}
}

懒汉式单例

同步锁(当然还有简单的,去掉synchronized,只是存在安全问题)

public class SingletonTest1 {//构造器私有化,防止外部调用private SingletonTest1() {}private static SingletonTest1 sin = null;//使用同步锁保证一定会创建,并且只会创建一次public static synchronized SingletonTest1 getInstance(){if(sin == null){sin = new SingletonTest1();}return sin;}
}

双重检测锁

public class SingletonTest2 {//构造器私有化,防止外部调用private SingletonTest2() {}//使用volatile,在这里的作用是禁止指令重排//sin = new SingletonTest2();不是一个原子操作//第一步、申请内存,第二步、初始化,第三步、地址引用给sin//如果第三步在第二步前面就执行了,此时另一个现场通过getInstance获取实例时进来判断就不为null了,直接返回,而这个时候其实还并没有实例化//synchronized只能保证代码块相较于外面是正常顺序,代码块内部还是可能由于指令优化导致第三步在第二步前面就执行了private static volatile SingletonTest2 sin = null;//为什么要判断两次呢//第一次是为了减少同步,不用每次进来都去加锁//第二次是如果现在有两个现场同时竞争锁,那必然有一个是处于阻塞状态的//当处于阻塞状态的线程拿到锁后,前面的线程肯定是已经创建过实例了//如果这个时候不判断一下的话就会有实例化一次public static SingletonTest2 getInstance(){if(sin == null){synchronized (SingletonTest2.class){if(sin == null){sin = new SingletonTest2();}}}return sin;}
}

内部类

public class SingletonTest3 {//构造器私有化,防止外部调用private SingletonTest3() {}private static SingletonTest3 sin = null;public static SingletonTest3 getInstance(){return SingletonClass.singleton;}//内部类只有在使用的时候才会初始化,其中初始化是jvm控制的,单线程操作,保证了线程安全,也实现了懒汉式private static class SingletonClass{private static SingletonTest3 singleton = new SingletonTest3();}
}

工厂模式

工厂模式主要是为了屏蔽创建对象的过程,主要分为三类(静态工厂,普通工厂,抽象工厂)

静态工厂(简单工厂)

public interface FactoryTest {void doSome();
}public class FactoryTest1 implements FactoryTest {@Overridepublic void doSome() {System.out.println("FactoryTest1");}
}public class FactoryTest2 implements FactoryTest {@Overridepublic void doSome() {System.out.println("FactoryTest2");}
}public class StaticFactory {public static FactoryTest creatTest(String name){if("FactoryTest1".equals(name)){return new FactoryTest1();}else if("FactoryTest2".equals(name)){return new FactoryTest2();}return null;}
}public class Test1 {public static void main(String[] args) {//通过StaticFactory工厂创建对应的实例类FactoryTest factoryTest1 = StaticFactory.creatTest("FactoryTest1");factoryTest1.doSome();FactoryTest factoryTest2 = StaticFactory.creatTest("FactoryTest2");factoryTest2.doSome();}
}

每次新增一个FactoryTest时,需要修改StaticFactory.creatTest()方法,这样不合理,所以有了普通工厂模式

普通工厂

public interface FactoryTest {void doSome();
}public class FactoryTest1 implements FactoryTest {@Overridepublic void doSome() {System.out.println("FactoryTest1");}
}public class FactoryTest2 implements FactoryTest {@Overridepublic void doSome() {System.out.println("FactoryTest2");}
}public interface ICommonFactory {FactoryTest createTest();
}public class CommonFactory1 implements ICommonFactory {@Overridepublic FactoryTest createTest() {return new FactoryTest1();}
}public class CommonFactory2 implements ICommonFactory {@Overridepublic FactoryTest createTest() {return new FactoryTest2();}
}public class Test1 {public static void main(String[] args) {//通过CommonFactory1工厂创建对应的实例类new CommonFactory1().createTest().doSome();new CommonFactory2().createTest().doSome();}
}

每次新增一个FactoryTest时,只需要新增一个对应的CommonFactory工厂实现类就行,对于之前的工厂和对象不影响

抽象工厂

现在有手机和平板,可以使用上述的普通工厂来创建,但现在给手机和平板分了牌子,有华为手机和苹果手机,华为平板和苹果平板,这样一个产品族的概念(分为手机和平板两个产品族,手机产品族里面包含了华为手机和苹果手机两个产品),那么就可以使用抽象工厂模式。

//手机产品族
public interface Phone {void doSome();
}
public class PhoneHuawei implements Phone {@Overridepublic void doSome() {System.out.println("华为手机");}
}
public class PhonePinguo implements Phone {@Overridepublic void doSome() {System.out.println("苹果手机");}
}//平板产品族
public interface Tablet {void doSome();
}
public class TabletHuawei implements Tablet {@Overridepublic void doSome() {System.out.println("华为平板");}
}
public class TabletPinguo implements Tablet {@Overridepublic void doSome() {System.out.println("苹果平板");}
}//工厂
public interface AbsFactory {Phone buyPhone();Tablet buyTablet();
}
//华为工厂
public class HuaweiFatory implements AbsFactory{@Overridepublic Phone buyPhone() {return new PhoneHuawei();}@Overridepublic Tablet buyTablet() {return new TabletHuawei();}
}
//苹果工厂
public class PinguoFatory implements AbsFactory{@Overridepublic Phone buyPhone() {return new PhonePinguo();}@Overridepublic Tablet buyTablet() {return new TabletPinguo();}
}public class Test1 {public static void main(String[] args) {HuaweiFatory huaweiFatory = new HuaweiFatory();huaweiFatory.buyPhone().doSome();huaweiFatory.buyTablet().doSome();PinguoFatory pinguoFatory = new PinguoFatory();pinguoFatory.buyPhone().doSome();pinguoFatory.buyTablet().doSome();}
}

相关文章:

【2023-05-09】 设计模式(单例,工厂)

2023-05-09 设计模式(单例,工厂) 单例模式 顾名思义,就是整个系统对外提供的实例有且只有一个 特点: ​ 1、单例类只有一个实例 ​ 2、必须是自己创建唯一实例 ​ 3、必须给所以对象提供这个实例 分类&#xff…...

批量任务导致页面卡死解决方案

需求背景 需要基于高德地图展示海量点位(大概几万个),点位样式要自定义(创建DOM),虽然使用了聚合点,但初始化时仍需要将几万个点位的DOM结构都创建出来。 这里补充一句,高德地图在2.…...

避免“文献综抄”,5种写作结构助你完成文献综述→

很多作者可能有过这样的体验:读了很多文献,但在写综述的时候总感觉不像是在写文献综述,更像在写文献总结 如果引用方面不注意,甚至会成为文献综抄。 那么,你可以参考下我们整理的以下资料哦~ 01 文献总结和文献综述的…...

Java异常和反射

JAVA 异常分类及处理 概念 } final Entry<K,V> getEntryUsingComparator(Object key) { K k (K) key; // 获取该 TreeMap 的 comparator Comparator<? super K> cpr comparator; if (cpr ! null) { // 从根节点开始 Entry<K,V> p …...

Accesss数据库的那点事

Accesss数据库的那点事 1.Access的简介 Access&#xff08;全称为Microsoft Access&#xff09;是一个关系型数据库管理系统&#xff08;RDBMS&#xff09;。它是由微软公司开发的数据库软件&#xff0c;用于创建、管理和操作数据库应用程序。 Access提供了一个可视化的开发环…...

网络基础学习:osi网络七层模型

osi网络七层模型 什么是OSI&#xff0c;什么是ISO?为什么ISO要提出OSI网络七层模型&#xff1f;OSI七层的划分以及具体内容第七层 应用层第六层 表示层第五层 会话层第四层 传输层第三层 网络层第二层 数据链路层第一层 物理层 每一层与设备的对应关系 什么是OSI&#xff0c;什…...

EndNote X9 引用参考 单击文献编号,不能跳转到文尾文献列表处,咋解决?文献编号 不能跳转 ,怎么办?

文章目录 1 正常情况下 引用文献编号 是可以跳转的2 问题分析3 解决方法4 EndNote X9 插入参考文献常见问题总结5 EndNote X9 快速上手教程&#xff08;毕业论文参考文献管理器&#xff09; 1 正常情况下 引用文献编号 是可以跳转的 正确的插入文献后&#xff0c; 正常情况下&a…...

用免费蜜罐工具配置Modbus工控蜜罐

导语&#xff1a;本文将用DecoyMini免费蜜罐工具来配置自定义的ModbusTCP工控仿真模板&#xff0c;并介绍部署后的Modbus蜜罐的使用效果。 DecoyMini是一个免费的蜜罐工具&#xff0c;其特色是仿真能力采用与软件松耦合的仿真模板来进行管理。通过一键式导入云端仿真模板库里的…...

DataGridXL中快速搜索单元格和底部全屏模式区域隐藏

DataGridXL表格是在2020年发布&#xff0c;DataGridXL在设计时就考虑到了性能。提供最快、最简单、最可靠的数据网格。DataGridXL支持所有常用所有的浏览器&#xff0c;为 Web 应用程序提供类似于 Microsoft Excel 的体验&#xff0c;它支持前端框架有Vue、React、Angular等。 …...

DotNet几种微服务框架,你用过吗?

最近有群友问&#xff0c;.NET有哪些微服务框架&#xff1f;.NET的微服务框架还真不多&#xff0c;一般企业都会自己搭建微服务框架&#xff0c;或者基于其它框架搭建微服务&#xff08;比如abp&#xff09;。本文将介绍几种微服务框架&#xff0c;供大家学习参考。 一、Servi…...

Nature | 生成式人工智能如何构建更好的抗体

疫情高峰期&#xff0c;研究人员竞相开发一些首批有效的COVID-19治疗方法&#xff1a;从已经康复的人的血液中分离出来的抗体分子。 现在&#xff0c;科学家已经证明&#xff0c;生成式人工智能&#xff08;AI&#xff09;可以通过一些繁琐的过程提供捷径&#xff0c;提出增强抗…...

【hive】基于Qt5和libuv udp 的lan chat

作者已经不更新了,但是很棒 在线用户列表: 聊天窗口 主程序 单独的网络线程: network_thread data管理关联网络管理的 程序update升级更新 和消息收到 即可...

Java版本工程项目管理系统源码,助力工程企业实现数字化管理

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…...

什么是零拷贝?

零拷贝 什么是零拷贝 零拷贝指的是&#xff0c;从一个存储区域到另一个存储区域的copy任务无需CPU参与就可完成。零拷贝的底层是 通过DMA总线技术实现的。零拷贝与具体的编程语言无关&#xff0c;完全依赖于OS&#xff0c;OS支持就可使用&#xff0c;不支持 设置了也不起作用…...

计算机专业含金量高的证书

目录 第一种证书&#xff1a;计算机技术与软件专业资格考试证书 第二种证书&#xff1a;微软认证 第三种证书&#xff1a;Oracle认证 第四种证书&#xff1a;思科认证 第五种证书&#xff1a;华为认证 第六种证书&#xff1a;红帽认证工程师 第七种证书&#xff1a;阿里…...

原装二手Keithley 2401低压源表 吉时利2401数字源表

Keithley 2401低压源表&#xff0c;20V&#xff0c;1A&#xff0c;20W Keithley 2401 低压源表提供精密电压和电流源和测量功能&#xff08;1V - 20V 和 10pA - 1A&#xff09;。它既是高度稳定的直流电源&#xff0c;又是真正的仪器级 5 位万用表。电源特性包括低噪声、精度和…...

gradle-8.1.1-all 快速下载百度网盘下载

Gradle 8.1.1 发布 这是Gradle 8.1的第一个补丁发布。 它修复了以下3个问题&#xff1a; 为配置缓存检测具有数千个lambdas的类时出现MethodTooLargeException&#xff1b;用Gradle 8.1构建的Kotlin DSL预编译脚本插件不能用于其他版本的Gradle&#xff1b;Gradle 8.1在buil…...

C#开发的OpenRA游戏之基地工程车部署命令产生过程

C#开发的OpenRA游戏之基地工程车部署命令产生过程 OpenRA游戏里,前面已经分析基地工程车部署的流程, 但那只是一个框架的流程,只能理解大体的框架, 如果想要深入一步了解怎么样产生部署命令,还需继续探讨以下的代码。 基地工程车是先选中,然后再在基地工程车上面点击右…...

C++ 智能指针的原理、分类、使用

1. 智能指针介绍 为解决裸指针可能导致的内存泄漏问题。如&#xff1a; a&#xff09;忘记释放内存&#xff1b; b&#xff09;程序提前退出导致资源释放代码未执行到。 就出现了智能指针&#xff0c;能够做到资源的自动释放。 2. 智能指针的原理和简单实现 2.1 智能指针的原…...

学习笔记——SVG.js中形状元素的创建及其相关方法

CreateElement 1&#xff09;创建svg元素 在svg.js中&#xff0c;每个元素都是一个对象&#xff0c;可以通过构造它来创建&#xff1a; import { Rect } from "svgdotjs/svg.js" var rect new Rect().size(100, 100).addTo(draw) // or to reuse an existing nod…...

别再让模型在Unity里‘抽风’了!Blender导出FBX到Unity的7步避坑自查清单

别再让模型在Unity里‘抽风’了&#xff01;Blender导出FBX到Unity的7步避坑自查清单当你花了三天三夜精心雕琢的Blender模型&#xff0c;导入Unity后却变成了一团旋转错乱、贴图闪烁的"抽象艺术"&#xff0c;那种崩溃感每个3D开发者都懂。本文将用实战经验帮你建立一…...

BetterJoy完整配置指南:5分钟让Switch手柄在PC上完美运行

BetterJoy完整配置指南&#xff1a;5分钟让Switch手柄在PC上完美运行 【免费下载链接】BetterJoy Allows the Nintendo Switch Pro Controller, Joycons and SNES controller to be used with CEMU, Citra, Dolphin, Yuzu and as generic XInput 项目地址: https://gitcode.c…...

自制BLE112串口编程器:基于Bootloader的免调试器烧录方案

1. 项目概述&#xff1a;为BLE112模块打造一款免调试器的RS232编程器在嵌入式开发&#xff0c;特别是早期的蓝牙低功耗&#xff08;BLE&#xff09;模块应用中&#xff0c;我们常常会遇到一个棘手的问题&#xff1a;官方开发工具链的依赖和限制。以Silicon Labs&#xff08;当时…...

告别FTP龟速:用NTFS-3G在CentOS7上直连移动硬盘拷贝200G大文件

告别FTP龟速&#xff1a;用NTFS-3G在CentOS7上直连移动硬盘拷贝200G大文件当面对数百GB的设计素材、日志文件或数据库备份需要迁移时&#xff0c;传统的FTP传输往往会成为效率瓶颈。我曾在一个视频处理项目中&#xff0c;需要将230GB的4K原始素材从移动硬盘导入服务器&#xff…...

AI算力要上天?别笑,太空数据中心真能干翻地球电费!

前言你有没有算过&#xff0c;训练一个大模型&#xff0c;相当于烧掉多少吨煤&#xff1f;如今AI狂飙突进&#xff0c;算力需求指数级增长&#xff0c;可地球上的电——不够用了&#xff01;更别说建个数据中心还得跟地方政府“斗智斗勇”&#xff0c;抢地皮、配储能、扛审批&a…...

基于随机森林的低成本传感器机器学习校准实践指南

1. 项目概述&#xff1a;当低成本传感器遇上机器学习校准在物联网和智能感知系统铺天盖地的今天&#xff0c;低成本传感器几乎无处不在。从监测办公室的空气质量&#xff0c;到追踪城市街道的噪音污染&#xff0c;再到农业大棚里的温湿度控制&#xff0c;这些价格亲民的“小眼睛…...

Unity塔防底层架构:ScriptableObject驱动的数据契约设计

1. 这不是“又一个塔防模板”&#xff0c;而是塔防开发的底层操作系统我第一次在Asset Store点开Tower Defense Toolkit 4&#xff08;TDTK-4&#xff09;的预览图时&#xff0c;下意识划走了——界面太“干净”了&#xff0c;没有炫酷的粒子特效演示&#xff0c;没有满屏飞舞的…...

揭秘Midjourney云雾渲染失效真相:3大隐性提示词冲突、2类SDXL迁移兼容漏洞及实时雾浓度校准公式

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;揭秘Midjourney云雾渲染失效真相&#xff1a;3大隐性提示词冲突、2类SDXL迁移兼容漏洞及实时雾浓度校准公式 Midjourney V6 在启用云雾&#xff08;mist/fog/haze&#xff09;类视觉效果时&#xff0c;…...

NsEmuTools:10分钟搞定NS模拟器配置,让你专注游戏乐趣

NsEmuTools&#xff1a;10分钟搞定NS模拟器配置&#xff0c;让你专注游戏乐趣 【免费下载链接】ns-emu-tools 一个用于安装/更新 NS 模拟器的工具 项目地址: https://gitcode.com/gh_mirrors/ns/ns-emu-tools 还在为NS模拟器的复杂配置而头疼吗&#xff1f;每次想玩Swit…...

告别Selenium?手把手教你用Playwright录制脚本,5分钟搞定Web自动化测试

5分钟极速上手Playwright脚本录制&#xff1a;零代码实现Web自动化测试当产品经理突然丢给你一个刚上线的电商活动页&#xff0c;要求半小时内完成所有核心链路测试时&#xff0c;传统的手写Selenium脚本显然来不及。作为测试工程师&#xff0c;我最近发现微软开源的Playwright…...