设计模式(工厂模式,模板方法模式,单例模式)
单例模式:
确保一个类只有一个实例,并提供全局访问点。
单例模式举例:
-
配置信息类:用于存储应用程序的全局配置信息,例如数据库连接信息、日志配置等。
-
日志类:用于记录应用程序运行时的日志信息,确保在整个应用程序中只有一个日志实例
-
线程池类:在多线程环境下,使用单例模式可以确保只有一个线程池实例,提高资源利用率和性能。
单例模式饿汉式:
代码:
public class Singleton {/*防止外界随意使用构造方法new对象,我们需要将构造私有化*/private Singleton(){}/*为了赶紧new对象,我们new对象的时候变成静态的,让其随着类的加载而加载为了不让外界随便使用类名调用此静态对象,我们将其变成private*/private static Singleton singleton = new Singleton();/*为了将内部new出来的对象给外界我们可以定义 一个方法,将内部的对象返回给外界*/public static Singleton getSingleton(){return singleton;}
}
将new出来的对象设置为静态属性,这样随着类的加载而加载
单例模式懒汉式:
public class Singleton1 {/*防止外界随意使用构造方法new对象,我们需要将构造私有化*/private Singleton1() {}/*懒汉式,不着急new对象*/private static Singleton1 singleton1 = null;/*为了将内部new出来的对给外界定义一个方法,将内部new出来的对返回*/public static Singleton1 getSingleton1() {//如果singleton1不是null就没必要抢锁了,直接返回,是null再抢锁if (singleton1==null){synchronized (Singleton1.class){if (singleton1 == null) {singleton1 = new Singleton1();}}}return singleton1;}
}
懒汉式就不着急new对象了,留了一个公共的接口,你想new的时候就new即可
懒汉式的线程不安全问题:
这也是懒汉式的一个缺点:如果没有加锁的代码:
public static Singleton1 getSingleton1() {if (singleton1 == null) {singleton1 = new Singleton1();}return singleton1;}
这很容易引发线程不安全问题,我们设想有两个线程,第一个线程需要这个singleton1这个对象,进入了if判断,不过这个时候CPU将线程切换给了第二个线程,那这个时候,第二个线程也进入了if判断,然后CPU再切换会第一个线程,线程一创建了对象,但是我们知道线程二也进入了if判断,它也能创建对象,这就导致了线程不安全问题
饿汉式和懒汉式区别:
1:创建的时间不一样:饿汉式是在类加载过程中就创建了实例,而饿汉式是被调用的时候才创建实例
2:线程安全问题:饿汉式不存在什么线程安全,类加载的时候我就创建了,而且不能改,不可能又线程安全问题,反观饿汉式就有线程安全问题
在Spring中的单例模式的体现:
在 Spring 源码中,最常见的使用单例设计模式的场景就是在创建 Bean 实例时使用单例模式。Spring 容器默认情况下会将所有的 Bean 对象作为单例对象进行管理,这样可以节省资源,提高性能。
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);@Overridepublic Object getSingleton(String beanName) {return this.singletonObjects.get(beanName);}@Overridepublic void registerSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {Object oldObject = this.singletonObjects.get(beanName);if (oldObject != null) {throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName +"': there is already object [" + oldObject + "] bound");}this.singletonObjects.put(beanName, singletonObject);}}// 其他方法...
}
这个是我在鱼皮公众号上看到的,我第一次看到这段话的时候,也是有一个疑问
创建 Bean 实例是饿汉式还是懒汉式?
然后我问了GPT:
Spring容器在启动时会预先实例化所有单例Bean对象,这样可以避免懒汉式中可能存在的线程安全问题,确保在需要使用Bean时能够立即获取到对象实例。这种预先实例化的方式类似于饿汉式,但并不完全等同于饿汉式的实现方式。
模板方法模式:
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。明确了一部分功能,而另一部分功能不明确。需要延伸到子类中实现
这个我觉得就非常好理解:
我们平常都在写的接口或者抽象类都是这种思想
比如我们要去餐馆吃饭,我们每次餐馆都要点菜买单
不过我们去不同的餐馆点的菜都不一样
就可以把餐馆抽象成一个类,不同的餐馆都是实现类
上一段代码:
public abstract class Hotel {public void eat(){System.out.println("点菜");eatCai();System.out.println("买单");}public abstract void eatCai();
}public class QuanJuDe extends Hotel{@Overridepublic void eatCai() {System.out.println("薄饼");System.out.println("放鸭肉");System.out.println("酱");System.out.println("葱丝");System.out.println("黄瓜丝");System.out.println("卷着吃");}
}
public class ZhangLiang extends Hotel{@Overridepublic void eatCai() {System.out.println("调麻酱");System.out.println("放辣椒油");System.out.println("倒到大碗中吃");}
}public class Test01 {public static void main(String[] args) {QuanJuDe quanJuDe = new QuanJuDe();quanJuDe.eat();System.out.println("================");ZhangLiang zhangLiang = new ZhangLiang();zhangLiang.eat();}
}
工厂模式:
工厂模式是一种创建型设计模式,其主要目的是封装对象的实例化过程,将对象的创建和使用分离。通过工厂模式,可以实现更灵活、可扩展的对象创建方式,同时降低代码的耦合度。
工厂模式分为下面三种:简单工厂模式,工厂方法模式,抽象工厂模式
还没有工厂的时候:我们如果需要车,我们得自己去造车 自己去 new 对象
public class BMW320 {public BMW320(){System.out.println("制造-->BMW320");}
}public class BMW523 {public BMW523(){System.out.println("制造-->BMW523");}
}public class Customer {public static void main(String[] args) {BMW320 bmw320 = new BMW320();BMW523 bmw523 = new BMW523();}
}
简单工厂模式:简单工厂的时候,我们已经有了简单的工厂,我们不用自己去造车了
我们可以告诉工厂,我们需要这个这个车,工厂造好给我们即可
有一个工厂类,我们去调用工厂类的造车方法造车
产品类:
// 产品接口
interface Product {void doSomething();
}// 具体产品类 A
class ConcreteProductA implements Product {@Overridepublic void doSomething() {System.out.println("Product A is doing something.");}
}// 具体产品类 B
class ConcreteProductB implements Product {@Overridepublic void doSomething() {System.out.println("Product B is doing something.");}
}
工厂类:
// 简单工厂类
class SimpleFactory {public static Product createProduct(String type) {if ("A".equals(type)) {return new ConcreteProductA();} else if ("B".equals(type)) {return new ConcreteProductB();}return null;}
}
客户端代码:
// 客户端代码
public class Main {public static void main(String[] args) {Product productA = SimpleFactory.createProduct("A");productA.doSomething();Product productB = SimpleFactory.createProduct("B");productB.doSomething();}
}
工厂方法模式:到了这个时候,随着车型的增多,一个工厂已经不能生成这么多车型了
就需要工厂分类:每个工厂生成一种型号的车
有一个工厂抽象类,生成各种型号的车的工厂去继承里面的造车方法
再有一个车的抽象类,不同的车去继承里面的方法
// 产品接口
interface Product {void doSomething();
}// 具体产品类 A
class ConcreteProductA implements Product {@Overridepublic void doSomething() {System.out.println("Product A is doing something.");}
}// 具体产品类 B
class ConcreteProductB implements Product {@Overridepublic void doSomething() {System.out.println("Product B is doing something.");}
}// 工厂接口
interface Factory {Product createProduct();
}// 具体工厂类 A,负责创建产品 A
class ConcreteFactoryA implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductA();}
}// 具体工厂类 B,负责创建产品 B
class ConcreteFactoryB implements Factory {@Overridepublic Product createProduct() {return new ConcreteProductB();}
}// 客户端代码
public class Main {public static void main(String[] args) {Factory factoryA = new ConcreteFactoryA();Product productA = factoryA.createProduct();productA.doSomething();Factory factoryB = new ConcreteFactoryB();Product productB = factoryB.createProduct();productB.doSomething();}
}
抽象工厂模式:这个时候的需求就已经很复杂了,
每个车需要的零件都不同,比如车1和车2分别是两个不同的型号,车1需要空调a和发动机b,车2需要空调b和发动机b
这个时候就设计到了一个产品族,就是空调,发动机或者其它产品合在一起就是一个产品族
有点像我们日常生活中开店,比如我们开冷冻产品店,那我们不可能一个人去准备所有的冷冻产品,我肯定是去找对应的供货商,比如火锅料的供货商,鱿鱼的供货商,饮料的供货商,然后整合到我这个冷冻店再去销售
所以翻译成Java语言就是,空调是一个抽象类,发动机是一个抽象类,多个抽象类,一个工厂抽象类,不同型号的车是一个类都去继承这个工厂,你需要什么零件就去这个工厂里面配这个零件。
// 产品族接口
interface AbstractProductA {void doSomething();
}interface AbstractProductB {void doSomething();
}// 具体产品类 A1
class ConcreteProductA1 implements AbstractProductA {@Overridepublic void doSomething() {System.out.println("Product A1 is doing something.");}
}// 具体产品类 B1
class ConcreteProductB1 implements AbstractProductB {@Overridepublic void doSomething() {System.out.println("Product B1 is doing something.");}
}// 具体产品类 A2
class ConcreteProductA2 implements AbstractProductA {@Overridepublic void doSomething() {System.out.println("Product A2 is doing something.");}
}// 具体产品类 B2
class ConcreteProductB2 implements AbstractProductB {@Overridepublic void doSomething() {System.out.println("Product B2 is doing something.");}
}// 抽象工厂接口
interface AbstractFactory {AbstractProductA createProductA();AbstractProductB createProductB();
}// 具体工厂类 1
class ConcreteFactory1 implements AbstractFactory {@Overridepublic AbstractProductA createProductA() {return new ConcreteProductA1();}@Overridepublic AbstractProductB createProductB() {return new ConcreteProductB1();}
}// 具体工厂类 2
class ConcreteFactory2 implements AbstractFactory {@Overridepublic AbstractProductA createProductA() {return new ConcreteProductA2();}@Overridepublic AbstractProductB createProductB() {return new ConcreteProductB2();}
}// 客户端代码
public class Main {public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();AbstractProductA productA1 = factory1.createProductA();AbstractProductB productB1 = factory1.createProductB();productA1.doSomething();productB1.doSomething();AbstractFactory factory2 = new ConcreteFactory2();AbstractProductA productA2 = factory2.createProductA();AbstractProductB productB2 = factory2.createProductB();productA2.doSomething();productB2.doSomething();}
}
相关文章:

设计模式(工厂模式,模板方法模式,单例模式)
单例模式: 确保一个类只有一个实例,并提供全局访问点。 单例模式举例: 配置信息类:用于存储应用程序的全局配置信息,例如数据库连接信息、日志配置等。 日志类:用于记录应用程序运行时的日志信息&#x…...

ES6 对象的新增方法(十四)
1. Object.assign(target, …sources) 特性:将一个或多个源对象的所有可枚举属性复制到目标对象。 用法:用于对象属性的合并。 const obj1 { a: 1, b: 2 }; const obj2 { b: 3, c: 4 }; Object.assign(obj1, obj2);console.log(obj1); // 输出&#…...

Spring Boot 学习总结(34)—— spring-boot-starter-xxx 和 xxx-spring-boot-starter 区别?
一、Spring Starter 简介 Spring Starter 是 Spring Boot 提供的一种便捷方式,帮助开发者快速集成和配置 Spring 应用中所需的依赖。每个 Starter 都是一个预配置的依赖集,可以自动配置应用的一部分或特定功能。这些 Starter 旨在消除手动编写大量样板代码和配置的需求。 1…...

昇思训练营打卡第二十五天(RNN实现情感分类)
RNN,即循环神经网络(Recurrent Neural Network),是一种深度学习模型,特别适用于处理序列数据。以下是对RNN的简要介绍: RNN的特点: 记忆性:与传统的前馈神经网络不同,R…...

昇思25天学习打卡营第02天|张量 Tensor
一、什么是张量 Tensor 张量是一种特殊的数据结构,与数组和矩阵非常相似。张量(Tensor)是MindSpore网络运算中的基本数据结构。 张量可以被看作是一个多维数组,但它比普通的数组更加灵活和强大,因为它支持在GPU等加速…...

权威认可 | 海云安开发者安全助手系统通过信通院支撑产品功能认证并荣获信通院2024年数据安全体系建设优秀案例
近日,2024全球数字经济大会——数字安全生态建设专题论坛(以下简称“论坛”)在京成功举办。由全球数字经济大会组委会主办,中国信息通信研究院及公安部第三研究所共同承办,论坛邀请多位专家和企业共同参与。 会上颁发…...

24.7.10|暑假-数组题目:实现整数的数字反转【学习记录】
1、题目: 32位有符号整数,将整数每位上的数字进行反转 输入:123 输出:321 输入:-123 输出:-321 输入:120 输出:21 !) 问题 怎么把整数转换成字符串ÿ…...

【ceph】ceph集群-添加/删除mon
本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…...

Django ORM中的Q对象
Q 对象在 Django ORM 中用于构建复杂的查询条件,特别是当你需要使用逻辑运算符(如 AND、OR、NOT)时。以下是一些使用 Q 对象进行复杂查询的实际例子。 Q对象使用 模型 假设我们有一个包含员工信息的模型 Employee: from djang…...

相控阵雷达原理详解
相控阵,即相位控制阵列,通过控制阵列各个单元的馈电相位来改变波束指向。 相控阵雷达的原理可以清晰地归纳为以下几点: 1. 基本构成: - 相控阵雷达,即相位控制电子扫描阵列雷达(Phased Array Radar, PAR&a…...

算法项目报告:物流中的最短路径问题
问题描述 物流问题 有一个物流公司需要从起点A到终点B进行货物运输,在运输过程中,该公司需要途径多个不同的城市,并且在每个城市中都有一个配送站点。为了最大程度地降低运输成本和时间,该公司需要确定经过哪些配送站点ÿ…...

linux中 crontab 定时器用法
*/10 * * * * python3 /home/code/haha2.py Crontab 当然,以下是一个简短的博客,介绍了 Cron 和 Crontab 的用法: --- # 简介:使用 Cron 和 Crontab 在 Linux 中进行定时任务调度 在 Linux 系统中,Cron 是一个用于…...

java算法day16
java算法day16 112 路径总和404 左叶子之和513 找树左下角的值 112 路径总和 题型判定为自顶向下类型,并且为路径和类型。 那就套模板。 自顶向下就是从上到下处理,那么就是前序遍历的思想。 class Solution {boolean res false;public boolean hasP…...

华为HCIP Datacom H12-821 卷41
1.多选题 以下关于BGP Atomic_Aggregate和Aggregator的描述,正确的是哪些项? A、Aggregator属性属于可选过渡属性 B、Atomic_Aggregate属于公认任意属性 C、收到携带Atomic_Aggregate属性的路由表示这条路由不能再度明细化 D、 Agregator表示某条路由可能出现…...

【React Hooks原理 - forwardRef、useImperativeHandle】
概述 上文我们聊了useRef的使用和实现,主要两个用途:1、用于持久化保存 2、用于绑定dom。 但是有时候我们需要在父组件中访问子组件的dom或者属性/方法,而React中默认是不允许父组件直接访问子组件的dom的,这时候就可以通过forwa…...

用于可穿戴传感器的人类活动识别、健康监测和行为建模的大型语言模型
这篇论文题为《用于可穿戴传感器的人类活动识别、健康监测和行为建模的大型语言模型:早期趋势、数据集和挑战的综述》,由埃米利奥费拉拉(Emilio Ferrara)撰写。论文主要内容如下: 摘要 可穿戴技术的普及使得传感器数…...

react事件绑定
react基础事件绑定 function passwordChange(e){console.log(e.target.value); } function usernameChange(e){console.log(e.target.value); }function App() {return (<div><input type"text" placeholder请输入用户名onChange{usernameChange}/><i…...

spring框架之AOP注解方式(java代码实例)
目录 半注解形式: 业务层接口实现类: 编写切面类: 在配置文件里面唯一需要加的: 测试类: 全注解形式: 不要配置文件,改为配置类: 同样的业务层接口实现类: 同样的…...

windows下gcc编译C、C++程序 MinGW编译器
文章目录 1、概要2、MinGW安装2.1 编译器下载2.2 编译器安装2.3 设置环境变量2.4 查看gcc版本信息 3、编译C、C程序3.1 编写Hello World.c3.2 编译C程序3.3 运行程序3.4 编译C程序 1、概要 GCC原名为GNU C语言编译器(GNU C Compiler),只能处…...

uniapp启动图延时效果,启动图的配置
今天阐述uniapp开发中给启动图做延迟效果,不然启动图太快了,一闪就过去了; 一:修改配置文件:manifest.json "app-plus" : {"splashscreen" : {"alwaysShowBeforeRender" : false,"…...

SQL,python,knime将数据混合的文字数字拆出来,合并计算(学习笔记)
将下面将数据混合的文字数字拆出来,合并计算 一、SQL解决: ---创建表插入数据 CREATE TABLE original_data (id INT AUTO_INCREMENT PRIMARY KEY,city VARCHAR(255),value DECIMAL(10, 2) );INSERT INTO original_data (city, value) VALUES (上海0.5…...

【算法】LRU缓存
难度:中等 题目: 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,…...

解决elementUI列表的疑难杂症,排序显示错乱的问题
大家好,在使用elementUI表格时,有时会出现一些意料之外的问题,比如数据排序正常但表格显示、排序错乱等。在网上搜索后一般有2种解决方法:1.给表格每一项的el-table-column添加唯一的id用于区分。2.给表格每一项的el-table-column…...

重大消息:手机车机互联投屏专题发布-千里马带你学框架
背景: android投屏的使用场景以前在新能源车机还没火爆时候,大部分停留在手机小屏幕投屏到大屏幕的情况及整个多端设备的互动,整体需求和技术发展其实也就是比较有限,但是新能源车机火爆后,那么这种手机和车机互联互动…...

jail子系统里升级Ubuntu focal到jammy
Ubuntu focal是20.04 ,jammy版本是22.04,本次的目的就是将FreeBSD jail子系统里的Ubuntu 从20.04升级到22.04 。这个focal 子系统是通过cbsd克隆得到的。使用CBSD克隆复制Ubuntu jail子系统环境-CSDN博客 do-release-upgrade升级没成功,用de…...

2024年7月20日(星期六)骑行支里山
2024年7月20日 (星期六)骑行支里山,早8:00到8:30,大观公园门口集合,9:00准时出发【因迟到者,骑行速度快者,可自行追赶偶遇。】 偶遇地点:大观公园门口集合 ,家住东,南,北…...

Python:正则表达式相关整理
最近因为一些原因频繁使用正则表达式,因为以前系统整理过关于正则表达式的相关知识,所以这里仅记录使用期间遇到的问题。 本文内容基于re包 1. match和search方法的区别 在Python中,re.search和re.match都是用于匹配字符串的正则表达式函数&a…...

ChatGPT对话:有关花卉数据集
【编者按】编者准备研究基于深度学习的花卉识别,首先需要花卉数据集。 后续,编者不断会记录研究花卉识别过程中的技术知识,敬请围观 1问:推荐一下用于深度学习的花卉数据集 ChatGPT 以下是一些用于深度学习的优秀花卉数据集&am…...

特征向量及算法
数据挖掘流程 加载数据 把需要的模型数据先计算出来 特征工程 提取数据特征,对特征数据进行清洗转化 数据的筛选和清洗数据转化 类型转为 性别 男,女 ----> 1,0特征交叉 性别/职业/收入 —> 新特这 优质男性程序员 将多个特征值组合在一起特征筛选…...

cpp 强制转换
一、static_cast static_cast 是 C 中的一个类型转换操作符,用于在类的层次结构中进行安全的向上转换(从派生类到基类)或进行不需要运行时类型检查的转换。它主要用于基本数据类型之间的转换、对象指针或引用的向上转换(即从派生…...