JAVA 中常用的设计模式,含案例和注释

news/2024/4/27 10:09:33/文章来源:https://blog.csdn.net/qq_62283694/article/details/129239743

JAVA 中常用的设计模式,含案例和注释

工厂模式(Factory Pattern)

工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象而不将创建逻辑暴露给客户端,并使用通用接口引用新创建的对象。

代码示例:

javaCopy code// 定义一个接口
interface Shape {void draw();
}// 定义具体的实现类
class Rectangle implements Shape {public void draw() {System.out.println("Rectangle draw method");}
}class Circle implements Shape {public void draw() {System.out.println("Circle draw method");}
}// 定义一个工厂类
class ShapeFactory {public Shape getShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {return new Rectangle();}return null;}
}// 使用工厂类创建对象
class FactoryPatternDemo {public static void main(String[] args) {ShapeFactory shapeFactory = new ShapeFactory();// 获取 Circle 的对象,并调用它的 draw 方法Shape shape1 = shapeFactory.getShape("CIRCLE");shape1.draw();// 获取 Rectangle 的对象,并调用它的 draw 方法Shape shape2 = shapeFactory.getShape("RECTANGLE");shape2.draw();}
}

单例模式(Singleton Pattern)

单例模式是一种创建型模式,它确保一个类只有一个实例,并提供对该实例的全局访问点。

代码示例:

javaCopy code// 使用饿汉式实现单例模式
class Singleton {// 创建 Singleton 的一个对象private static Singleton instance = new Singleton();// 让构造函数为 private,这样该类就不会被实例化private Singleton() {}// 获取唯一可用的对象public static Singleton getInstance() {return instance;}public void showMessage() {System.out.println("Hello World!");}
}// 使用 Singleton 类来获取唯一的对象
class SingletonPatternDemo {public static void main(String[] args) {Singleton singleton = Singleton.getInstance();singleton.showMessage();}
}

适配器模式(Adapter Pattern)

适配器模式是一种结构型设计模式,它能够将不兼容的对象包装成适配器对象,从而使得原本因为接口不兼容而无法一起工作的类可以一起工作。

在适配器模式中,有三种角色:

  • Target(目标接口):客户端所期望的接口,适配器对象要实现该接口。
  • Adaptee(被适配者):需要被适配的对象或类,它定义了客户端不能直接调用的接口。
  • Adapter(适配器):将被适配者包装成目标接口的对象。

以下是一个简单的例子,其中 AudioPlayer 是目标接口,MediaPlayer 是被适配者,MediaAdapter 是适配器:

AudioPlayer.java:

javaCopy codepublic class AudioPlayer implements MediaPlayer {MediaAdapter mediaAdapter;@Overridepublic void play(String audioType, String fileName) {//播放 mp3 音乐文件的内置支持if (audioType.equalsIgnoreCase("mp3")) {System.out.println("Playing mp3 file. Name: " + fileName);}//mediaAdapter 提供了播放其他文件格式的支持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");}}
}

MediaPlayer.java:

javaCopy codepublic interface MediaPlayer {public void play(String audioType, String fileName);
}

AdvancedMediaPlayer.java:

javaCopy codepublic interface AdvancedMediaPlayer {public void playVlc(String fileName);public void playMp4(String fileName);
}

VlcPlayer.java:

javaCopy codepublic class VlcPlayer implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName) {System.out.println("Playing vlc file. Name: "+ fileName);}@Overridepublic void playMp4(String fileName) {//什么也不做}
}

Mp4Player.java:

javaCopy codepublic class Mp4Player implements AdvancedMediaPlayer{@Overridepublic void playVlc(String fileName) {//什么也不做}@Overridepublic void playMp4(String fileName) {System.out.println("Playing mp4 file. Name: "+ fileName);}
}

MediaAdapter.java:

javaCopy codepublic 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);}}
}

我们可以使用适配器模式,使得客户端可以通过 AudioPlayer 接口播放 vlc 或 mp4 。

代理模式(Proxy Pattern)

代理模式是一种常见的结构型设计模式,用于在不改变原始类(或对象)代码的情况下,为其提供一种间接的访问方式,从而实现对其行为进行控制或增强。

代理模式主要有三种形式:静态代理、动态代理和虚拟代理。其中,静态代理需要手动编写代理类,而动态代理和虚拟代理则可以使用Java反射机制进行自动生成。

以下是一个使用静态代理模式实现简单的缓存代理的示例代码,其中实现了一个接口UserService,并通过一个代理类UserServiceProxy来实现对其方法的缓存代理。

javaCopy code// 定义一个接口
public interface UserService {public void addUser(String userName);
}// 实现接口的原始类
public class UserServiceImpl implements UserService {public void addUser(String userName) {System.out.println("Add user: " + userName);}
}// 代理类,实现了同样的接口,并持有原始类的实例
public class UserServiceProxy implements UserService {private UserService userService;private Map<String, String> cache;public UserServiceProxy(UserService userService) {this.userService = userService;this.cache = new HashMap<>();}// 代理方法,首先从缓存中查找,如果不存在则调用原始类方法,并将结果放入缓存public void addUser(String userName) {if (cache.containsKey(userName)) {System.out.println("User " + userName + " already exists.");} else {userService.addUser(userName);cache.put(userName, userName);System.out.println("User " + userName + " added.");}}
}// 使用代理类
public class Client {public static void main(String[] args) {UserService userService = new UserServiceImpl();UserServiceProxy proxy = new UserServiceProxy(userService);proxy.addUser("Tom");proxy.addUser("Jerry");proxy.addUser("Tom"); // 从缓存中获取}
}

在上述示例代码中,UserServiceProxy类是一个代理类,它实现了UserService接口,并持有一个UserService类型的实例。在代理类中实现了addUser方法,首先从缓存中查找是否已存在该用户,如果存在则直接返回,否则调用原始类UserServiceImpladdUser方法,并将结果放入缓存。这样,在使用代理类时,就可以自动实现对方法的缓存代理,从而提高程序的运行效率。

需要注意的是,以上示例中的代理模式为静态代理模式,需要手动编写代理类。如果需要实现动态代理或虚拟代理,则可以使用Java反射机制来自动生成代理类,从而简化程序的编写和维护。

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

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

相关文章

线上研讨会报名 | Perforce、中手游、星思半导体专家邀您一起畅聊如何通过数字资产管理与版本控制赋能大规模研发

全球领先的数字资产管理与DevSecOps工具厂商Perforce联合中国授权合作伙伴龙智举办的Perforce on Tour网络研讨会将于2月28日下午2:00举行。 本次研讨会以“赋能‘大’研发&#xff0c;助力‘快’交付”为主题&#xff0c;龙智董事长何明、Perforce高级顾问Robert Cowham&…

Spring中的FactoryBean 和 BeanFactory、BeanPostProcessor 和BeanFactoryPostProcessor解析

文章目录FactoryBean 和 BeanFactory后置处理器BeanPostProcessor 和 BeanFactoryPostProcessorBeanPostProcessorBeanFactoryPostProcessorFactoryBean 和 BeanFactory BeanFactory接⼝是容器的顶级接⼝&#xff0c;定义了容器的⼀些基础⾏为&#xff0c;负责⽣产和管理Bean的…

2.26selenium常用api

一.等待1.线程强制等待Thread.sleep()2.隐式等待driver.manage().timeouts().implicitlyWait(Duration.ofSeconds())3.显式等待WebDriverWait foo new WebDriverWait(driver,Duration.ofSeconds(10));foo.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector()…

Spring Boot整合Kaptcha实现验证码功能

目录一、前言1.Kaptcha 简介2.Kaptcha 详细配置表二、实现1.整合kaptcha&#xff0c;创建kaptcha的工具类1.1 添加依赖1.2 创建KaptchaConfig工具类2 编写接口&#xff0c;在接口中使用 kaptcha 工具类来生成验证码图片&#xff08;验证码信息&#xff09;并返回3 登录时从sess…

特斯拉4D雷达方案首次曝光!高阶智驾市场比拼安全冗余

随着L2级智能驾驶进入普及阶段&#xff0c;L3/L4级赛道正在成为各家车企的下一个竞争焦点。背后的最大难题&#xff0c;就是如何在成本可控的前提下&#xff0c;保证足够的安全。 高工智能汽车研究院监测数据显示&#xff0c;2022年度中国市场&#xff08;不含进出口&#xff…

Nginx搭建域名访问(负载均衡到网关)

1.修改Nginx总配置 配置上游服务器 多个网关换行 2.修改Nginx服务的配置 直接代理到上游服务&#xff08;网关&#xff09; 页面给Nginx发送请求&#xff0c;带Host&#xff0c;但是Nginx给网关转的时候会丢掉Host&#xff0c;所以要单独配上 3.修改网关微服务配置 安装ho…

追梦之旅【数据结构篇】——详解C语言实现二叉树

详解C语言实现二叉树~&#x1f60e;前言&#x1f64c;什么是二叉树&#xff1f;二叉树的性质总结&#xff1a;整体实现内容分析&#x1f49e;1.头文件的编写&#xff1a;&#x1f64c;2.功能文件的编写&#xff1a;&#x1f64c;1&#xff09;前序遍历的数值来创建树——递归函…

mysql索引分析之二

mysql索引分析之一 mysql索引分析之二 mysql索引分析之二1 mysql的索引类型2 Explain执行计划2.1 执行计划之 id 属性2.1.1 id 的属性相同表示加载表的顺序是从上到下2.1.2 id 值越大&#xff0c;优先级越高2.1.3 id 有相同&#xff0c;也有不同&#xff0c;同时存在2.2 执行计…

嵌入式系统硬件设计与实践(第一步下载eda软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 现实生活中&#xff0c;我们经常发现有的人定了很多的目标&#xff0c;但是到最后一个都没有实现。这听上去有点奇怪&#xff0c;但确实是实实在在…

【华为OD机试模拟题】用 C++ 实现 - 能力组队(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明能力组队题目输入输出示例一输入输出说明示例二输入输出Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 O…

Word处理控件Aspose.Words功能演示:使用 C++ 在 Word (DOC/DOCX) 中添加或删除水印

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c; Aspose API支持流行文件格式处…

Python实现贝叶斯优化器(Bayes_opt)优化LightGBM分类模型(LGBMClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。1.项目背景贝叶斯优化器(BayesianOptimization) 是一种黑盒子优化器&#xff0c;用来寻找最优参数。贝叶斯优化器是基…

第50天|LeetCode739. 每日温度、LeetCode496. 下一个更大元素 I

1.题目链接&#xff1a;739. 每日温度 题目描述&#xff1a; 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&a…

使用docker pull 跨系统架构拉取镜像

使用docker pull 跨系统架构拉取镜像使用docker pull 跨系统架构拉取镜像docker hub上找到相应的镜像在个人电脑中的执行拉取镜像命令&#xff1a;执行查看镜像命令&#xff1a;执行检查镜像命令&#xff1a;执行保存镜像命令&#xff1a;使用docker pull 跨系统架构拉取镜像 …

断点续传实现

断点续传 1、 什么是断点续传 通常视频文件都比较大&#xff0c;所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制&#xff0c;但是客户的网络环境质量、电脑硬件环境等参差不齐&#xff0c;如果一个大文件快上传完了网断了没有上…

高频面试题|RabbitMQ如何防止消息的重复消费?

一. 前言最近有很多小伙伴开始找工作&#xff0c;在面试时&#xff0c;面试官经常会问我们这样一个题目&#xff1a;RabbitMQ如何防止重复消费?有很多小伙伴这个时候都在想&#xff0c;消息怎么还会重复消费呢???.......所以他们在面试后就跑来问壹哥&#xff0c;针对这个比…

Python实现GWO智能灰狼优化算法优化循环神经网络回归模型(LSTM回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。1.项目背景灰狼优化算法(GWO)&#xff0c;由澳大利亚格里菲斯大学学者 Mirjalili 等人于2014年提出来的一种群智能优…

针对面试官的盘问-如何回答职场中的一些问题

(点击即可收听)初入职场,面对面试官的提问,如何回答01你为什么从上家公司离职?个人成长不足,不符合自己的预期&#xff08;关系到个人竞争力,希望找到一份更有挑战,个人提升更大的工作&#xff09;,切忌与面试官倒苦水,说前公司老板的不是业务发展缓慢,上升空间有限(有些不符合…

力扣-换座位

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;626. 换座位二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总结前言 …

redis(11)事务秒杀案例

秒杀案例描述 现在有1个秒杀的功能&#xff0c;1个原来价值5000元的手机现在搞活动&#xff0c;降价到1块钱&#xff0c;做秒杀活动。库存就10个&#xff0c;假设有10000人抢购。 目前逻辑是&#xff1a;抢到了商品库存就减1&#xff0c;然后把用户id加入到秒杀成功者清单中 Re…