设计模式在Java中的应用:从单例模式到工厂模式的全面解析!

全文目录:

    • 开篇语
    • 前言
    • 1. 单例模式:确保全局只有一个实例
      • 1.1 饿汉式单例
      • 1.2 懒汉式单例
      • 1.3 双重检查锁定(DCL)
    • 2. 工厂模式:简化对象创建
      • 2.1 简单工厂模式
      • 2.2 工厂方法模式
      • 2.3 抽象工厂模式
    • 3. 其他设计模式
      • 3.1 观察者模式
      • 3.2 策略模式
      • 3.3 适配器模式
    • 4. 结语
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

设计模式,是面向对象设计中的“秘籍”,帮助我们解决程序设计中遇到的一些常见问题。它们是基于多年开发经验总结出来的解决方案,不仅能提升代码的复用性、可维护性和扩展性,还能使我们在开发过程中避免重复造轮子。在Java中,设计模式的应用更是几乎无处不在,帮助我们优化架构、提升开发效率。

今天我们将重点讲解几个常见的设计模式,具体包括单例模式工厂模式,以及其他一些经典的设计模式,如观察者模式策略模式适配器模式。在这个过程中,我们不仅要知道“为什么”使用这些模式,更要知道“如何”使用它们。

1. 单例模式:确保全局只有一个实例

单例模式是一个非常常见的设计模式,它的核心思想是:保证一个类只有一个实例,并提供一个全局的访问点。这个模式特别适用于控制资源的使用,比如数据库连接池、线程池等。单例模式不仅能避免多个实例造成的资源浪费,还能控制类的实例化过程,确保一致性。

1.1 饿汉式单例

饿汉式单例是在类加载时就创建单例对象,因此它是线程安全的,且实现简单。但是,这种方式缺点在于,不管是否需要该实例,类加载时就会进行实例化。

public class Singleton {// 在类加载时初始化实例private static final Singleton INSTANCE = new Singleton();// 私有化构造函数private Singleton() {}// 提供公共方法获取实例public static Singleton getInstance() {return INSTANCE;}
}

这种方式的缺点是:如果你只在某些情况下需要这个单例实例,它依然会在类加载时就创建好,这可能造成性能上的浪费。不过,它在高并发场景下是线程安全的。

1.2 懒汉式单例

懒汉式单例则是在需要的时候才实例化对象,这样可以避免不必要的资源浪费。然而,懒汉式单例在并发场景下存在问题,可能导致多线程下创建多个实例。

public class Singleton {// 声明静态变量,但不初始化private static Singleton instance;// 私有化构造函数private Singleton() {}// 提供公共方法获取实例public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

上面的代码在多线程环境下会出现问题,如果多个线程同时进入getInstance()方法,可能会导致多个实例的创建。为了避免这种情况,我们使用sychronized进行同步。但是,性能上并不是最优。

1.3 双重检查锁定(DCL)

双重检查锁定(Double-Checked Locking)是为了优化懒汉式单例的性能问题。它通过两次检查instance是否为空,第一次检查是在同步块外部,第二次检查则是在同步块内部。这种方式既能保证线程安全,又能避免每次都进行同步,提升了性能。

public class Singleton {private static volatile Singleton instance;// 私有化构造函数private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

volatile关键字用于保证instance变量在多线程环境下的可见性,确保所有线程都能看到最新的instance值。双重检查锁定提供了较高的性能,是懒汉式单例的优化版本。

2. 工厂模式:简化对象创建

工厂模式是一种创建对象的设计模式,目的是为了将对象的创建过程与使用过程分离,从而提高代码的可维护性和扩展性。工厂模式的基本思想是定义一个用于创建对象的接口,由具体的工厂类实现该接口。

2.1 简单工厂模式

简单工厂模式又叫静态工厂方法,它通过一个工厂类来决定哪个类的实例应该被创建。工厂类根据不同的条件(如传入的参数)来返回不同的对象。

public class AnimalFactory {public static Animal createAnimal(String type) {if ("Dog".equals(type)) {return new Dog();} else if ("Cat".equals(type)) {return new Cat();}return null;}
}

在这个简单的工厂模式中,AnimalFactory类根据传入的type来决定返回哪个具体的动物实例。该模式的缺点是,如果新增了一个Animal子类,我们需要修改工厂方法,违背了开闭原则。

2.2 工厂方法模式

工厂方法模式是对简单工厂模式的进一步抽象。每一个具体的工厂都继承自一个抽象工厂类,通过不同的工厂来创建对象。这样一来,当需要新增一个产品时,我们只需要新增一个工厂类,而不需要修改原有代码,符合开闭原则。

public abstract class AnimalFactory {public abstract Animal createAnimal();
}public class DogFactory extends AnimalFactory {@Overridepublic Animal createAnimal() {return new Dog();}
}public class CatFactory extends AnimalFactory {@Overridepublic Animal createAnimal() {return new Cat();}
}

2.3 抽象工厂模式

抽象工厂模式进一步扩展了工厂方法模式,它不仅能生产一个产品类别的对象,还能生产多个相关的对象。例如,一个“动物工厂”可能不仅仅生产狗、猫,还可以生产它们的相关对象,如“狗的玩具”或“猫的食品”。

public interface AnimalFactory {Animal createAnimal();Toy createToy();
}public class DogFactory implements AnimalFactory {public Animal createAnimal() {return new Dog();}public Toy createToy() {return new DogToy();}
}

通过这种方式,我们不仅可以创建不同类型的动物,还能创建与动物相关的产品。抽象工厂模式使得我们能够在多个产品族之间进行切换,且能够扩展更多产品类别而无需修改现有代码。

3. 其他设计模式

3.1 观察者模式

观察者模式是一种行为型设计模式,主要用于对象间的一对多关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。观察者模式广泛应用于事件驱动系统,比如GUI系统中的事件监听,或者消息推送等场景。

public interface Observer {void update(String message);
}public class ConcreteObserver implements Observer {private String name;public ConcreteObserver(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " received: " + message);}
}public class Subject {private List<Observer> observers = new ArrayList<>();public void addObserver(Observer observer) {observers.add(observer);}public void notifyObservers(String message) {for (Observer observer : observers) {observer.update(message);}}
}

3.2 策略模式

策略模式是一种行为型设计模式,定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。

public interface PaymentStrategy {void pay();
}public class CreditCardPayment implements PaymentStrategy {@Overridepublic void pay() {System.out.println("Paying with Credit Card");}
}public class PayPalPayment implements PaymentStrategy {@Overridepublic void pay() {System.out.println("Paying with PayPal");}
}

3.3 适配器模式

适配器模式是一种结构型设计模式,允许我们将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。

public interface MediaPlayer {void play(String fileName);
}public class AudioPlayer implements MediaPlayer {@Overridepublic void play(String fileName) {System.out.println("Playing audio: " + fileName);}
}public interface AdvancedMediaPlayer {void playMP4(String fileName);
}public class MP4Player implements AdvancedMediaPlayer {@Overridepublic void playMP4(String fileName) {System.out.println("Playing MP4: " + fileName);}
}public class MediaAdapter implements MediaPlayer {private AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(AdvancedMediaPlayer advancedMusicPlayer) {this.advancedMusicPlayer = advancedMusicPlayer;}@Overridepublic void play(String fileName) {advancedMusicPlayer.playMP4(fileName);}
}

4. 结语

设计模式的应用,可以帮助我们更好地管理复杂的系统结构,提升代码的灵活性、可维护性和可扩展性。在实际开发中,根据具体需求合理选用不同的设计模式,能让我们的代码更加优雅和高效。希望今天的内容能帮助你对这些经典设计模式有更深入的理解,并在实际开发中游刃有余地运用它们!

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

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

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

相关文章

Meta AIUCSD放大招:DeepConf 让大语言模型推理既快又准,84.7%的token节省+近乎完美的准确率!

1. 【前言】 Meta&UCSD 大语言模型&#xff08;LLMs&#xff09; 在推理任务中通过自一致性等测试时缩放方法展现出巨大潜力&#xff0c;但存在精度收益递减和计算开销高的问题。为此&#xff0c;Meta与UCSD的研究人员提出DeepConf方法&#xff0c;它利用模型内部的置信度信…

解决leetcode第3671.子序列美丽值求和问题

3671. 子序列美丽值求和难度&#xff1a;困难问题描述&#xff1a;给你一个长度为 n 的整数数组 nums。对于每个 正整数 g&#xff0c;定义 g 的 美丽值 为 g 与 nums 中符合要求的子序列数量的乘积&#xff0c;子序列需要 严格递增 且最大公约数&#xff08;GCD&#xff09;恰…

电机控制(一)-电机分类

电机分类 电机分类&#xff1a; 电机的拓扑模型并没有发生太大变化,变化较大的是控制电机的方法。 常见的电机类型有&#xff1a; 步进电机vs伺服电机 在工业自动化、机器人、精密设备等领域&#xff0c;步进电机和伺服电机是两种最常用的驱动电机&#xff0c;但两者的核心…

【Qt】QToolBar、QToolButton的常用用法

一、QToolBar 常用用法 QToolBar 是 Qt 中用于创建工具栏的控件&#xff0c;可快速放置常用功能按钮、分隔符或自定义控件&#xff0c;并支持拖动停靠、浮动等特性。 1. 基础创建与添加到主窗口 // 在 QMainWindow 中创建工具栏 QToolBar *toolBar new QToolBar(tr("主工…

DVWA靶场通关笔记-验证码绕过Insecure CAPTCHA (Impossible级别)

目录 一、reCAPTCHA 1、配置security为Impossible级别。 2、配置RECAPTCHA参数 3、再次打开靶场 二、源码分析 1、index.php 2、impossible.php 3、功能函数 三、reCAPTCHA 防范分析 1、严格的参数验证与处理 2、预处理防止SQL注入 3、CAPTCHA 验证通过 4、验证当前…

MySQL安装(如果之前有安装过MySQL,先执行下面的卸载流程)

1.安装MySQL 1.1更新系统的软件包列表 sudo apt-get update1.2安装MySQL服务器 sudo apt-get install mysql-server1.3检查MySQL服务是否启动&#xff0c;若没有启动手动启动若没有启动执行&#xff1a; sudo service mysql start1.4登录MySQL&#xff08;默认安装之后不需要密…

Streamlit 数据看板模板:非前端选手快速搭建 Python 数据可视化交互看板的实用工具

你想想看&#xff0c;平时你用 Python 跑出来一堆数据 —— 比如用户留存率、产品销量变化&#xff0c;想给领导或者同事看&#xff0c;总不能直接发个 CSV 文件或者一堆静态图吧&#xff1f;对方看的时候还得自己翻数据&#xff0c;想对比下上个月和这个月的变化都费劲&#x…

FMC、FMC+ 详解

文章目录FMC 简介FMC 引脚输出定义High-pin count (HPC) connector, HPC pinoutLow-pin count (LPC) connector, LPC pinoutPin and signal descriptionFMC 简介VITA57 标准更新历史VITA57.4 标准推出的原因FMC 引脚输出定义Altera 开发板的 FMC 引脚定义英特尔 Arria 10 GX FP…

小迪web自用笔记24

黑名单机制。如果被过滤可以试试PHP5看看过滤没&#xff08;或者其他变种变形&#xff09;&#xff0c;但是得看环境有些环境会被当成下载&#xff0c;有些会直接打开。白名单机制只允许这几个特定后缀可以上传&#xff0c;比黑名单更安全。直接从信息图中获取文件类型。文件类…

私有部署问卷系统、考试系统、投票系统、测评系统的最佳选择-调问开源问卷表单(DWSurvey)

在选择私有部署问卷系统的时候&#xff0c;调问问卷系统(DWSurvey)是一定要尝试一下&#xff0c;而且可以应用到私有部署考试系统、私有部署投票系统、私有部署测评系统等多个应用场景。 私有部署问卷、考试、测评、投票系统的优势不言而喻&#xff0c;就拿私有部署考试系统来说…

企业实用——MySQL的备份详解

序言: 本次基于mysql8.0.40来给大家做数据库的备份的实用技巧和思路!对于mysql基础的部分后续我会节选部分给大家讲解,本篇文章适合有一定数据库基础的小伙伴看。 目录 一、MySQL备份概述 1、关于数据保存你要知道 2、到底要备份什么 备份什么 MySQL体系结构(MySQL =…

使用 FunASR 工具包实现音频文件的语音识别

使用 FunASR 工具包实现音频文件的语音识别&#xff0c;并将识别结果保存为文本文件&#xff0c;支持单文件处理和批量处理。电脑环境需要配置&#xff0c;我使用的PyTorch版本: 2.4.1cu121&#xff0c;CUDA可用: True。FunASR 是一个功能强大、性能卓越、面向工业应用的语音识…

【STM32】定时器编码器接口

【STM32】定时器编码器接口一、编码器接口1.1 正交编码器1.2 编码器接口基本结构1.3 工作模式二、编码器接口测速一、编码器接口 编码器接口可接收增量&#xff08;正交&#xff09;编码器的信号&#xff0c;根据编码器旋转产生的正交信号脉冲&#xff0c;自动控制CNT的自增或…

浪潮科技Java开发面试题及参考答案(120道题-中)

请介绍一下 SpringMVC 的运行流程&#xff1f;从用户发送请求到响应返回的完整步骤是什么&#xff1f;SpringMVC 是基于MVC架构的Web框架&#xff0c;其运行流程围绕“前端控制器&#xff08;DispatcherServlet&#xff09;”展开&#xff0c;通过多个组件协同工作&#xff0c;…

k8s初始化常见问题

执行初始化&#xff1a;kubeadm init --apiserver-advertise-address192.168.88.110 --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr10.244.0.0/16 --control-plane-endpointweb01报错信息&#xff1a;age-repository registry.aliyuncs.com/…

Python学习笔记--使用Django修改和删除数据

一、修改方式一&#xff1a;模型类的对象.属性 更改的属性值&#xff0c;模型类的对象.save()返回值&#xff1a;编辑的模型类的对象。def update_book(request):book models.Book.objects.filter(pk1).first()book.price "169"book.save()return HttpResponse(bo…

如何评价2025年数学建模国赛?

2025年全国大学生数学建模竞赛将于9月4日正式举行&#xff01; 有些第一次参加数学竞赛的同学可能觉得自己还没准备好&#xff0c;临近比赛感到紧张很正常&#xff0c;但需调整心态——数学建模比赛本就是学习过程&#xff0c;遇到不会的知识及时搜索、现学现用即可&#xff0…

uniapp [全端兼容] - 实现全景图Vr 720°全景效果查看预览功能,3D全景图流畅不卡顿渲染+手势拖拽+悬浮工具按钮,uniAPP实现vr看720度全景效果示例代码(H5小程序APP全兼容)

前言 如果您需要 Vue 版本,请访问 这篇文章。 在 uni-app 全平台兼容(H5网页网站、支付宝/微信小程序、安卓App、苹果App、nvue)开发中,详细实现全景图Vr 720全景查看+用户可流畅拖动预览+自定义工具栏/按钮元素等,uniApp如何实现在线观看720度全景图,适用于全景图VR看房…

51单片机-实现串口模块教程

本章概述思维导图&#xff1a;51单片机实现串口模块教程通信基本概念通信&#xff0c;至少是需要两个对象&#xff0c;一个收一个发数据。根据数据通信的传输时序协调方式&#xff0c;可分为&#xff1a;同步通信和异步通信&#xff1b;根据数据通信的传输线路可分为&#xff1…

Linux echo 命令使用说明

echo 命令使用说明&#xff08;Linux&#xff09; 适用环境 Bash/Zsh 等常见 Shell&#xff08;echo 通常为内建命令&#xff09;也可能存在外部 /bin/echo&#xff08;行为与内建略有差异&#xff09; 基本语法 echo [选项] [字符串...]常用选项 -n: 结尾不输出换行-e: 解析反…