深入理解Java的设计模式

设计模式(Design Patterns)是软件开发中的宝贵经验总结,提供了解决常见设计问题的模板和最佳实践。在Java开发中,设计模式尤为重要,因为它们能够提高代码的可维护性、可扩展性和可重用性。本篇博客将详细介绍几种常见的设计模式,帮助读者掌握如何在Java开发中应用这些模式。

什么是设计模式?

设计模式是软件设计中反复出现的解决方案。它们不是具体的代码,而是关于如何解决某一类型问题的一般性描述。设计模式通常分为三大类:

  1. 创建型模式:关注对象的创建方式。
  2. 结构型模式:关注类和对象的组合。
  3. 行为型模式:关注类和对象之间的交互。

创建型模式

单例模式(Singleton Pattern)

单例模式确保一个类只有一个实例,并提供一个全局访问点。单例模式在需要控制资源的唯一性时非常有用,例如数据库连接、线程池等。

public class Singleton {private static Singleton instance;private Singleton() {// 私有构造函数,防止外部实例化}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
优点
  • 控制实例数量,节省资源。
  • 提供全局访问点。
缺点
  • 多线程环境下需要考虑同步问题。
  • 可能违背单一职责原则,因为类既要管理实例的创建,又要执行其他任务。

工厂模式(Factory Pattern)

工厂模式通过定义一个创建对象的接口来实现对象的实例化,而不是直接通过new操作符。这样可以使得创建过程与使用过程分离。

interface Shape {void draw();
}class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Circle");}
}class Square implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Square");}
}class ShapeFactory {public Shape getShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("SQUARE")) {return new Square();}return null;}
}
优点
  • 封装创建逻辑,代码更简洁。
  • 易于扩展,增加新类型无需修改现有代码。
缺点
  • 增加了系统的复杂性,需要更多的类和接口。

结构型模式

适配器模式(Adapter Pattern)

适配器模式将一个类的接口转换成客户端期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作。

interface MediaPlayer {void play(String audioType, String fileName);
}class AudioPlayer implements MediaPlayer {@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("mp3")) {System.out.println("Playing mp3 file. Name: " + fileName);}}
}interface AdvancedMediaPlayer {void playVlc(String fileName);void playMp4(String fileName);
}class VlcPlayer implements AdvancedMediaPlayer {@Overridepublic void playVlc(String fileName) {System.out.println("Playing vlc file. Name: " + fileName);}@Overridepublic void playMp4(String fileName) {// do nothing}
}class Mp4Player implements AdvancedMediaPlayer {@Overridepublic void playVlc(String fileName) {// do nothing}@Overridepublic void playMp4(String fileName) {System.out.println("Playing mp4 file. Name: " + fileName);}
}class MediaAdapter implements MediaPlayer {AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(String audioType) {if (audioType.equalsIgnoreCase("vlc")) {advancedMusicPlayer = new VlcPlayer();} else if (audioType.equalsIgnoreCase("mp4")) {advancedMusicPlayer = new Mp4Player();}}@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("vlc")) {advancedMusicPlayer.playVlc(fileName);} else if (audioType.equalsIgnoreCase("mp4")) {advancedMusicPlayer.playMp4(fileName);}}
}class AudioPlayerAdapter implements MediaPlayer {MediaAdapter mediaAdapter;@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("mp3")) {System.out.println("Playing mp3 file. Name: " + fileName);} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType, fileName);} else {System.out.println("Invalid media. " + audioType + " format not supported");}}
}
优点
  • 解耦客户端与服务端接口。
  • 增强代码的复用性。
缺点
  • 增加代码复杂性。
  • 可能导致过多的适配器类。

装饰者模式(Decorator Pattern)

装饰者模式通过将对象放入包含行为的特殊封装对象中来动态地扩展对象的功能。

interface Shape {void draw();
}class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Rectangle");}
}abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape) {this.decoratedShape = decoratedShape;}public void draw() {decoratedShape.draw();}
}class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw();setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape) {System.out.println("Border Color: Red");}
}public class DecoratorPatternDemo {public static void main(String[] args) {Shape rectangle = new Rectangle();Shape redRectangle = new RedShapeDecorator(new Rectangle());System.out.println("Rectangle with normal border");rectangle.draw();System.out.println("\nRectangle with red border");redRectangle.draw();}
}
优点
  • 动态扩展对象功能。
  • 避免使用继承扩展类功能。
缺点
  • 增加了许多小对象,复杂度提高。
  • 不容易调试。

行为型模式

策略模式(Strategy Pattern)

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户端。

interface Strategy {int doOperation(int num1, int num2);
}class OperationAdd implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}
}class OperationSubtract implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;}
}class OperationMultiply implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 * num2;}
}class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public int executeStrategy(int num1, int num2) {return strategy.doOperation(num1, num2);}
}public class StrategyPatternDemo {public static void main(String[] args) {Context context = new Context(new OperationAdd());System.out.println("10 + 5 = " + context.executeStrategy(10, 5));context = new Context(new OperationSubtract());System.out.println("10 - 5 = " + context.executeStrategy(10, 5));context = new Context(new OperationMultiply());System.out.println("10 * 5 = " + context.executeStrategy(10, 5));}
}
优点
  • 算法可自由切换。
  • 避免使用多重条件判断语句。
  • 提高算法的扩展性。
缺点
  • 客户端必须知道所有策略类,并自行决定使用哪一个策略类。
  • 策略模式会增加系统中类的数量。

观察者模式(Observer Pattern)

观察者模式定义了对象间的一对多依赖关系,当一个对象改变状态时,其所有依赖者都会收到通知并自动更新。

import java.util.ArrayList;
import java.util.List;class Subject {private List<Observer> observers = new ArrayList<>();private int state;public int getState() {return state;}public void setState(int

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

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

相关文章

四轮麦轮平衡车四个轮子安放位置要求,以及编码器测速注意事项(强调,否则无法正常平移)——基于STM32F103ZET6

轮子推荐ABBA&#xff0c;当然BAAB也可以 如图安放&#xff1a; 这两种安防位置可以实现平移效果 若要实现平移则需要先实现PID控制平衡&#xff0c;这里用到520编码电机&#xff0c;相较于370电机他的动力更足&#xff0c;在调节PID时能节约不少时间而且更加容易。 需要注意…

存放Google key的芯片中安全区域能否作为POS机的安全芯片SP存放密钥使用?

能否当作SP使用&#xff1f; 存放Google key的芯片中安全区域是否能作为POS机的安全芯片&#xff08;Secure Processor, SP&#xff09;存放密钥使用&#xff0c;这个问题涉及几个关键方面&#xff1a; 硬件安全性&#xff1a; 安全级别&#xff1a;POS机用于处理支付信息&…

uniapp项目 使用vue-plugin-hiprint静默打印功能

插件地址&#xff1a;https://toscode.mulanos.cn/gyy155/vue-plugin-hiprint h5项目使用插件的静默打印功能 1.下载vue-plugin-hiprint和jquery npm install vue-plugin-hiprint npm install jquery --save2.在mian.js引入插件和jqerry //引入vue-plugin-hiprint import { h…

git 检查用户是否是gitlab用户

背景: 公司代码要从老的git库迁到新的git库&#xff0c;老git库上部分提交用户在新git库上没有&#xff0c;解决方法: 让gitlab不再检查提交用户是否是gitlab用户。具体操作: 去掉下面的勾选&#xff0c;保存配置即可。

金融数据库,实时行情,股票财务数据在线查询

jvQuant在线SQL 文档(current)接入 测试 查询 #股票代码股票简称最新价(元)2024-05-21股东总户数(户)截至2024-05-21上市板块是否ST股票区间涨跌幅(%)2024-05-15-2024-05-21市盈率(TTM)(倍)2024-05-21营业收入(元)截至2024-03-31总市值(元)2024-05-21量比2024-05-21利润率(%…

qt实现秒表功能

最近项目里需要一个计时功能&#xff0c;可以实现暂停&#xff0c;继续&#xff0c;结束&#xff0c;开始的功能&#xff0c;如同秒表一样&#xff0c;我就写了一个demo&#xff0c;效果如图&#xff1a; 代码如下&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include &l…

深入解析与实现:变分自编码器(VAE)完整代码详解

VAE理论上一篇已经详细讲完了&#xff0c;虽然VAE已经是过去的东西了&#xff0c;但是它对后面强大的生成模型是很有指导意义的。接下来&#xff0c;我们简单实现一下其代码吧。 1 VAE在minist数据集上的实现 完整的代码如下&#xff0c;没有什么特别好讲的。 import cv2 im…

代码随想录算法训练营day31 | 491.递增子序列、46.全排列、47.全排列 II

491.递增子序列 未去重的代码 class Solution:def findSubsequences(self, nums: List[int]) -> List[List[int]]:result []self.backtracking(nums, result, [], 0)return resultdef backtracking(self, nums, result, path, startIndex):if len(path) > 2:result.ap…

【代码随想录】【算法训练营】【第20天】 [654]最大二叉树 [617]合并二叉树 [700]二叉搜索树中的搜索 [98]验证二叉搜索树

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 19&#xff0c;一个愉快的周日~ day 20&#xff0c;一个悲伤的周一~ 题目详情 [654] 最大二叉树 题目描述 654 最大二叉树 解题思路 前提&#xff1a;构造二叉树 思路&#xff1a;寻找根节…

python两个列表如何取交集

在Python编程中&#xff0c;我们经常需要处理各种数据集合&#xff0c;包括列表&#xff08;list&#xff09;。有时候&#xff0c;我们可能想要找出两个列表中的共同元素&#xff0c;这通常被称为取交集。下面&#xff0c;我将介绍几种在Python中实现两个列表取交集的方法。 …

如何设置XHSC(华大)单片机的IO口中断

XHSC(华大)单片机IO口中断使用 一、代码说明 华大单片机的历程在华大或者小华的官网上都可以下载到,但是我们下载的历程基本注释都是非常简单,有的还没有注释;再加上小华跟华大的历程在代码架构上有所区别,所以新手在直接调用华大或者小华历程后,历程代码的可读性并不…

内网安全--域渗透准备知识

目录 知识点&#xff1a; 0x01 0x02 0x03 系列点&#xff1a; Linux主机信息收集 windows主机信息收集 知识点&#xff1a; 0、域产生原因 1、内网域的区别 2、如何判断在域内 3、域内常见信息收集 4、域内自动化工具收集 -局域网&工作组&域环境区别 -域…

Hinton揭秘GPT之父【Ilya】成长历程:Scaling Law是他学生时代就有的直觉

2003年夏天的一个周日&#xff0c;AI教父Hinton在多伦多大学的办公室里敲代码&#xff0c;突然响起略显莽撞的敲门声。门外站着一位年轻的学生&#xff0c;说自己整个夏天都在打工炸薯条&#xff0c;但更希望能加入Hinton的实验室工作。Hinton问&#xff0c;你咋不预约呢&#…

SQLite 如何导出某些SQLite3表的数据

https://deepinout.com/sqlite/sqlite-questions/44_sqlite_how_do_i_dump_the_data_of_some_sqlite3_tables.html 要导出整个SQLite3数据库的数据&#xff0c;可以使用SQLite3的.dump命令。首先&#xff0c;打开终端或命令提示符&#xff0c;并进入SQLite3终端会话。然后&…

# LLM高效微调详解-从Adpter、PrefixTuning到LoRA

一、背景 目前NLP主流范式是在大量通用数据上进行预训练语言模型训练&#xff0c;然后再针对特定下游任务进行微调&#xff0c;达到领域适应&#xff08;迁移学习&#xff09;的目的。 Context Learning v.s. SFT 指令微调是预训练语言模型微调的主流范式&#xff0c;其目的是…

嵌入式C语言--基础知识

嵌入式C语言–基础知识 嵌入式C语言--基础知识 嵌入式C语言--基础知识一. 含参数的宏与函数的不同点1&#xff09;函数2&#xff09;宏 二. scanf格式化输入的注意事项三. 指针1&#xff09;指针变量(地址变量&#xff09;2&#xff09;指针常见含义 四. 数组五. 数组与指针的区…

解读 Nginx:构建高效反向代理和负载均衡的秘密

解读 Nginx&#xff1a;构建高效反向代理和负载均衡的秘密 一、简介 Nginx (Engine-X) 是一个高性能的 HTTP 和反向代理服务器&#xff0c;也是一个 IMAP/POP3/SMTP 代理服务器。Nginx 以其高并发、高可靠性、低内存消耗等特点&#xff0c;成为了众多互联网公司首选的服务器软…

通用代码生成器应用场景三,遗留项目反向工程

通用代码生成器应用场景三&#xff0c;遗留项目反向工程 如果您有一个遗留项目&#xff0c;要重新开发&#xff0c;或者源代码遗失&#xff0c;或者需要重新开发&#xff0c;但是希望复用原来的数据&#xff0c;并加快开发。 如果您的项目是通用代码生成器生成的&#xff0c;…

在智慧城市建设中,大数据发挥着怎样的关键作用?

在智慧城市建设中&#xff0c;大数据发挥着以下关键作用&#xff1a; 数据采集与监测&#xff1a;大数据技术能够帮助城市采集和监测各种数据&#xff0c;包括气象、环境、交通、能源等方面的数据。这些数据可以用来分析和预测城市的运行情况&#xff0c;并为城市的各个部门提供…

阿里云产品DTU评测报告(二)

阿里云产品DTU评测报告&#xff08;二&#xff09; 问题回顾问题处理继续执行 问题回顾 基于上一次DTU评测&#xff0c;在评测过程中遇到了windows系统情况下执行amp命令失败的情况&#xff0c;失败情况如图 导致后续命令无法执行&#xff0c;一时之间不知如何处理&#xff0…