Java 中的设计模式:经典与现代实践
Java 中的设计模式:经典与现代实践
1. 设计模式简介
设计模式是一种软件开发中的思想,它为我们提供了一些经过验证的、能够应对常见问题的解决方案。学习和掌握设计模式能够让开发者在面对复杂的需求时,能够设计出更加灵活、可维护的代码。现代 Java 语言的特点(如 Lambda 表达式、Stream API、Optional)使得设计模式的实现更加简洁和高效。
设计模式按照其功能可以分为三大类:
- 创建型模式:用于对象创建,避免直接实例化。
- 结构型模式:用于类和对象的组合,解决系统中类之间的关系问题。
- 行为型模式:描述对象之间的交互和职责划分。
在这篇文章中,我们将通过现代 Java 的特性来重构经典设计模式的实现,帮助开发者更好地理解和运用设计模式。
2. 创建型设计模式
2.1 工厂模式(Factory Pattern)
经典实现
工厂模式通过封装对象的创建逻辑,将客户端与具体类的实例化解耦。通常适用于在创建对象时需要复杂逻辑或者希望通过参数控制生成不同对象的场景。
经典代码示例
// 产品接口
public interface Car {void drive();
}// 具体产品类
public class BMW implements Car {@Overridepublic void drive() {System.out.println("Driving BMW...");}
}public class Audi implements Car {@Overridepublic void drive() {System.out.println("Driving Audi...");}
}// 工厂类
public class CarFactory {public static Car createCar(String type) {switch (type.toLowerCase()) {case "bmw": return new BMW();case "audi": return new Audi();default: throw new IllegalArgumentException("Unknown car type");}}
}
现代 Java 实现:使用 Lambda 表达式
我们可以使用 Lambda 表达式来简化工厂模式的实现,减少冗长的 if-else
或 switch
语句,使得代码更简洁、灵活。
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;public class CarFactory {private static final Map<String, Supplier<Car>> carRegistry = new HashMap<>();static {carRegistry.put("bmw", BMW::new);carRegistry.put("audi", Audi::new);}public static Car createCar(String type) {Supplier<Car> carSupplier = carRegistry.get(type.toLowerCase());if (carSupplier == null) {throw new IllegalArgumentException("Unknown car type");}return carSupplier.get();}
}
Spring 框架中的工厂模式
在 Spring 框架中,ApplicationContext
就是工厂模式的实现,它负责实例化并管理 Bean。
// Spring 通过工厂模式实例化 Bean
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = context.getBean("car", Car.class);
car.drive();
3. 结构型设计模式
3.1 代理模式(Proxy Pattern)
经典实现
代理模式通过引入代理对象来控制对真实对象的访问。代理对象可以在调用目标对象之前或之后增加额外的逻辑,比如日志、权限控制等。
经典代码示例
// 服务接口
public interface UserService {void createUser(String username);
}// 真实服务类
public class RealUserService implements UserService {@Overridepublic void createUser(String username) {System.out.println("Creating user: " + username);}
}// 代理类
public class UserServiceProxy implements UserService {private final RealUserService realUserService = new RealUserService();@Overridepublic void createUser(String username) {System.out.println("Logging: Start creating user");realUserService.createUser(username);System.out.println("Logging: End creating user");}
}
现代 Java 实现:使用 Java 8 的 Stream
和 Optional
我们可以利用 Java 8 的 Optional 来避免 null
值的处理,并使用 Stream API 来简化数据的处理。
public class UserServiceProxy implements UserService {private final RealUserService realUserService = new RealUserService();@Overridepublic void createUser(String username) {Optional.of(username).filter(name -> !name.isEmpty()).ifPresentOrElse(name -> {System.out.println("Logging: Start creating user");realUserService.createUser(name);System.out.println("Logging: End creating user");},() -> System.out.println("Invalid username"));}
}
Spring AOP 中的代理模式
Spring 的 AOP(面向切面编程)就是利用代理模式来增强目标方法的功能。Spring 使用 JDK 动态代理 或 CGLIB 代理 来生成代理对象。
@Service
public class OrderService {@Transactionalpublic void createOrder() {// 事务管理由代理类处理}
}
4. 行为型设计模式
4.1 策略模式(Strategy Pattern)
经典实现
策略模式通过定义一系列算法并将每个算法封装到独立的策略类中,使得算法的选择和使用变得灵活。策略模式能够在运行时动态地改变策略。
经典代码示例
public interface PaymentStrategy {void pay(int amount);
}public class CreditCardPayment implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("Paying " + amount + " using Credit Card");}
}public class PayPalPayment implements PaymentStrategy {@Overridepublic void pay(int amount) {System.out.println("Paying " + amount + " using PayPal");}
}public class PaymentContext {private PaymentStrategy strategy;public void setPaymentStrategy(PaymentStrategy strategy) {this.strategy = strategy;}public void executePayment(int amount) {strategy.pay(amount);}
}
现代 Java 实现:使用 Stream
进行策略选择
可以通过 Stream API 来简化策略的选择过程,让代码更加简洁和优雅。
public class PaymentContext {private Map<String, PaymentStrategy> strategies = Map.of("credit", new CreditCardPayment(),"paypal", new PayPalPayment());public void executePayment(String paymentType, int amount) {Optional.ofNullable(strategies.get(paymentType)).ifPresentOrElse(strategy -> strategy.pay(amount),() -> System.out.println("Invalid payment method"));}
}
Spring 中的策略模式
Spring 中的 HandlerMapping
就是使用策略模式的一个例子,它通过不同的请求类型和处理器选择不同的处理策略。
public interface HandlerAdapter {boolean supports(Object handler);ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}
不同类型的 HandlerAdapter
处理不同的 Controller
,如 SimpleControllerHandlerAdapter
处理 SimpleController
。
5. 模板方法模式(Template Method Pattern)
经典实现
模板方法模式通过定义一个算法的骨架,将某些步骤的实现延迟到子类中。这样,子类可以在保留算法结构的同时定制部分实现。
经典代码示例
public abstract class DataProcessor {public void process() {readData();processData();writeData();}protected abstract void readData();protected abstract void processData();protected abstract void writeData();
}public class CSVDataProcessor extends DataProcessor {@Overrideprotected void readData() {System.out.println("Reading CSV data...");}@Overrideprotected void processData() {System.out.println("Processing CSV data...");}@Overrideprotected void writeData() {System.out.println("Writing CSV data...");}
}
现代 Java 实现:使用 Lambda 表达式和 Optional
我们可以结合 Lambda 表达式 来动态传入处理步骤,让模板方法的使用更加灵活。
public abstract class DataProcessor {public void process() {processStep(this::readData, "Reading");processStep(this::processData, "Processing");processStep(this::writeData, "Writing");}private void processStep(Runnable step, String stepName) {System.out.println(stepName + " data...");step.run();}protected abstract void readData();protected abstract void processData();protected abstract void writeData();
}
6. 总结
通过结合现代 Java 特性,我们可以让经典的设计模式变得更加简洁和高效。 Lambda 表达式 和 Stream API 为我们的设计模式实现提供了更灵活的方式,而 Optional 可以帮助我们避免空指针异常,使得代码更加健壮。
在实际的项目开发中,理解和运用设计模式能够大大提高代码的可维护性和可扩展性。希望本文的示例能够帮助你更好地理解设计模式,并在实际开发中灵活运用。
相关文章:
Java 中的设计模式:经典与现代实践
Java 中的设计模式:经典与现代实践 1. 设计模式简介 设计模式是一种软件开发中的思想,它为我们提供了一些经过验证的、能够应对常见问题的解决方案。学习和掌握设计模式能够让开发者在面对复杂的需求时,能够设计出更加灵活、可维护的代码。…...

DRG_DIP 2.0时代医院程序结构转型与数据结构优化研究
一、引言 1.1 DRG_DIP 2.0 改革背景与意义 医保支付方式改革在医疗保障制度改革中占据着极为关键的地位,是推动医疗领域变革的核心力量。它犹如一把精准的手术刀,对医疗资源的合理分配、医疗服务质量的稳步提升以及医疗费用的有效控制起着决定性作用。…...

一部手机如何配置内网电脑同时访问内外网
做过运维的朋友都知道,最麻烦的是运维电脑不能远程,每次都得现场进行维护,明明客户那边有可以访问内网的电脑,怎么操作能将这台电脑能访问跟到外网呢,这样不就能通过远程软件远程了吗?嘿嘿。按以下步骤试试…...
国产低功耗带LCD驱动和触摸按键功能的MCU
以下是国产低功耗、集成LCD驱动和触摸按键功能的MCU精选型号及其核心特性,结合性能、功耗和适用场景进行综合推荐: 1.灵动微MM32L0130系列 257 核心特性:低功耗:待机模式功耗低至100nA,支持多种低功耗模式。 LCD驱动&a…...

XCP 协议基础
文章目录 一、XCP 简介二、XCP的主要功能三、什么是标定四、什么时候进行标定五、标定的意义六、标定的三层架构XCP协议 和 CCP协议的区别参考 一、XCP 简介 XCP 协议的全称为 eXtended Calibration Protocol,即扩展标定协议。 另有其他定义,XCP 协议全…...
Swift 中 Codable 和 Hashable 的理解
最近初学Swift,碰到下面的代码脑袋里冒出疑问:Codable 和 Hashable是啥?怎么理解? struct Landmark: Hashable, Codable {var id: Intvar name: Stringvar park: Stringvar state: Stringvar description: String }针对上面的疑问…...
基于 WPF 平台实现成语游戏
一、引言 在软件开发领域,利用各种框架开发有趣的应用程序是提升技术能力和增加开发乐趣的有效方式。WPF(Windows Presentation Foundation)作为微软强大的桌面应用开发框架,提供了丰富的图形和交互功能。本文将带领大家基于 WPF…...

2024“博客之星”——我的博客成长与技术洞察
🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 目录 一、引言二、个人成长与突破盘点(一)技能提升与知识拓展(二)创作风格与影响力提升…...
HTTPS协议简述
HTTPS 协议简介 HTTPS 是 HTTP Security 的组合,即在 HTTP 的基础上加入了安全性机制,主要通过加密传输、身份认证和数据完整性保护来确保通信的安全性。 为了实现这一目标,HTTPS 引入了 加密技术,包括对称加密、非对称加密和数…...

前沿技术趋势洞察:2024年技术的崭新篇章与未来走向!
引言 时光飞逝,2024年已经来临,回顾过去一年,科技的迅猛进步简直让人目不暇接。 在人工智能(AI)越来越强大的今天,我们不再停留在幻想阶段,量子计算的雏形开始展示它的无穷潜力,Web …...
HTML常用属性
HTML标签的常见属性包括许多不同的功能,可以为元素提供附加信息或控制元素的行为。以下是一些常见的属性及其解释: 1. src 描述:src(source)属性指定一个资源的路径,通常用于图像、音频、视频等标签。常见…...

电子应用设计方案100:智能家庭AI电风扇系统设计
智能家庭 AI 电风扇系统设计 一、引言 智能家庭 AI 电风扇系统旨在为用户提供更加舒适、便捷和个性化的吹风体验,通过融合人工智能技术和先进的控制算法,实现智能化的风速调节、风向控制和场景适应。 二、系统概述 1. 系统目标 - 实现精准的风速调节&a…...

ThinkPHP 8请求处理-获取请求对象与请求上下文
【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用Composer初始化ThinkPHP 8应用_thinkphp8 compos…...
工厂模式 - 工厂方法模式、抽象工厂模式
引言 工厂模式(Factory Pattern)是设计模式中创建型模式的一种,它提供了一种创建对象的最佳方式。工厂模式的核心思想是将对象的创建与使用分离,使得代码更加灵活、可扩展。工厂模式主要分为两种:工厂方法模式和抽象工…...
2025年已过6%
前些阵子,注意到一个网站的年度进度条显示今年已完成4%的进度,而今天是1月22日,再一看已过去6%。如果1个月按30天来计算,1个月也就占一年1/12,差不多在8%-9%左右。 也许你会感觉这6%过得很快,也许你会感觉这…...

C#,入门教程(04)——Visual Studio 2022 数据编程实例:随机数与组合
上一篇: C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果https://blog.csdn.net/beijinghorn/article/details/123478581 C#,入门教程(01)—— Visual Studio 2022 免费安装的详细图文与动画教程https://blog.csdn.net…...

UWB高精度定位技术在智能仓储中的应用
在智能化和数字化转型的浪潮中,UWB高精度定位系统逐渐成为企业优化仓储管理和生产调度的关键技术。结合RFID标签打印机和服装生产型ERP软件,这一技术为企业带来了全新的管理方式和效率提升。 UWB高精度定位系统的核心优势 UWB(超宽带&…...

计算机毕业设计hadoop+spark视频推荐系统 短视频推荐系统 视频流量预测系统 短视频爬虫 视频数据分析 视频可视化 视频大数据 大数据
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

【AI编辑器】字节跳动推出AI IDE——Trae,专为中文开发者深度定制
目录 一、背景 二、核心特性 2.1 AI驱动的代码自动生成 2.2 智能问答与代码补全 2.3 多语言支持 2.4 插件与扩展 三、架构 四、下载使用 4.1 下载与安装 4.2 界面与配置 五、应用实践 5.1 快速生成代码 5.2 智能问答与调试 5.3 团队协作与代码审查 六、与Cursor…...

CSDN 博客之星 2024:默语的技术进阶与社区耕耘之旅
CSDN 博客之星 2024:默语的技术进阶与社区耕耘之旅 🌟 默语,是一位在技术分享与社区建设中坚持深耕的博客作者。今年,我有幸再次入围成为 CSDN 博客之星TOP300 的一员,这既是对过往努力的肯定,也是对未来探…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...
大数据驱动企业决策智能化的路径与实践
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:数据驱动的企业竞争力重构 在这个瞬息万变的商业时代,“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...

作为点的对象CenterNet论文阅读
摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表,并对每一个位置进行分类。这种做法既浪费又低效,并且需要额外的后处理。在本文中,我们采取了不同的方法。我们将物体建模为单…...