当前位置: 首页 > news >正文

Java 设计模式最佳实践:构建可维护的应用

Java 设计模式最佳实践:构建可维护的应用

别叫我大神,叫我 Alex 就好。

一、引言

大家好,我是 Alex。设计模式是软件开发中解决常见问题的可重用方案。它们是经过验证的最佳实践,可以帮助我们构建更可维护、更可扩展的应用。今天,我想和大家分享一下 Java 中常用的设计模式及其最佳实践,帮助大家更好地应用这些模式。

二、设计模式概述

设计模式分为三大类:

  1. 创建型模式:负责对象的创建,包括单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
  2. 结构型模式:负责对象的组合,包括适配器模式、桥接模式、装饰器模式、组合模式、外观模式、享元模式、代理模式
  3. 行为型模式:负责对象的行为,包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

三、创建型模式

1. 单例模式

用途:确保一个类只有一个实例,并提供一个全局访问点

实现方式

  • 饿汉式:类加载时创建实例
  • 懒汉式:首次使用时创建实例
  • 双重检查锁定:避免线程安全问题
  • 静态内部类:利用类加载机制保证线程安全
  • 枚举:最简洁、最安全的实现方式

示例

// 枚举实现(推荐) enum Singleton { INSTANCE; public void doSomething() { System.out.println("Singleton is doing something"); } } // 使用 Singleton.INSTANCE.doSomething(); // 静态内部类实现 public class Singleton { private Singleton() {} private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }

2. 工厂模式

用途:创建对象时不暴露创建逻辑,而是使用共同的接口来指向新创建的对象

实现方式

  • 简单工厂:一个工厂类负责创建所有产品
  • 工厂方法:每个产品有对应的工厂类
  • 抽象工厂:创建相关或依赖对象的家族

示例

// 产品接口 interface Product { void use(); } // 具体产品 class ConcreteProductA implements Product { @Override public void use() { System.out.println("Using Product A"); } } class ConcreteProductB implements Product { @Override public void use() { System.out.println("Using Product B"); } } // 工厂接口 interface Factory { Product createProduct(); } // 具体工厂 class ConcreteFactoryA implements Factory { @Override public Product createProduct() { return new ConcreteProductA(); } } class ConcreteFactoryB implements Factory { @Override public Product createProduct() { return new ConcreteProductB(); } } // 使用 Factory factory = new ConcreteFactoryA(); Product product = factory.createProduct(); product.use();

3. 建造者模式

用途:将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示

实现方式

  • 产品类:需要构建的复杂对象
  • 建造者接口:定义构建产品的方法
  • 具体建造者:实现建造者接口
  • 指挥者:负责使用建造者构建产品

示例

// 产品类 class Product { private String partA; private String partB; private String partC; public void setPartA(String partA) { this.partA = partA; } public void setPartB(String partB) { this.partB = partB; } public void setPartC(String partC) { this.partC = partC; } @Override public String toString() { return "Product{" + "partA='" + partA + '\'' + ", partB='" + partB + '\'' + ", partC='" + partC + '\'' + '}'; } } // 建造者接口 interface Builder { void buildPartA(); void buildPartB(); void buildPartC(); Product getResult(); } // 具体建造者 class ConcreteBuilder implements Builder { private Product product = new Product(); @Override public void buildPartA() { product.setPartA("Part A"); } @Override public void buildPartB() { product.setPartB("Part B"); } @Override public void buildPartC() { product.setPartC("Part C"); } @Override public Product getResult() { return product; } } // 指挥者 class Director { public Product construct(Builder builder) { builder.buildPartA(); builder.buildPartB(); builder.buildPartC(); return builder.getResult(); } } // 使用 Director director = new Director(); Builder builder = new ConcreteBuilder(); Product product = director.construct(builder); System.out.println(product);

四、结构型模式

1. 适配器模式

用途:将一个类的接口转换成客户端期望的另一个接口,使得原本不兼容的类可以一起工作

实现方式

  • 类适配器:通过继承实现
  • 对象适配器:通过组合实现

示例

// 目标接口 interface Target { void request(); } // 适配者类 class Adaptee { public void specificRequest() { System.out.println("Adaptee's specific request"); } } // 类适配器 class ClassAdapter extends Adaptee implements Target { @Override public void request() { specificRequest(); } } // 对象适配器 class ObjectAdapter implements Target { private Adaptee adaptee; public ObjectAdapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void request() { adaptee.specificRequest(); } } // 使用 Target target1 = new ClassAdapter(); target1.request(); Target target2 = new ObjectAdapter(new Adaptee()); target2.request();

2. 装饰器模式

用途:动态地给对象添加额外的责任,增强对象的功能

实现方式

  • 组件接口:定义对象的接口
  • 具体组件:实现组件接口
  • 装饰器:实现组件接口,并包含组件的引用
  • 具体装饰器:实现具体的装饰功能

示例

// 组件接口 interface Component { void operation(); } // 具体组件 class ConcreteComponent implements Component { @Override public void operation() { System.out.println("ConcreteComponent's operation"); } } // 装饰器 abstract class Decorator implements Component { protected Component component; public Decorator(Component component) { this.component = component; } @Override public void operation() { component.operation(); } } // 具体装饰器 class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void operation() { super.operation(); addBehavior(); } private void addBehavior() { System.out.println("ConcreteDecoratorA's additional behavior"); } } class ConcreteDecoratorB extends Decorator { public ConcreteDecoratorB(Component component) { super(component); } @Override public void operation() { super.operation(); addBehavior(); } private void addBehavior() { System.out.println("ConcreteDecoratorB's additional behavior"); } } // 使用 Component component = new ConcreteComponent(); Component decoratedComponent = new ConcreteDecoratorB(new ConcreteDecoratorA(component)); decoratedComponent.operation();

3. 代理模式

用途:为其他对象提供一个代理,以控制对这个对象的访问

实现方式

  • 静态代理:手动创建代理类
  • 动态代理:运行时生成代理类,如 JDK 动态代理、CGLIB

示例

// 接口 interface Subject { void request(); } // 真实主题 class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject's request"); } } // 静态代理 class StaticProxy implements Subject { private RealSubject realSubject; public StaticProxy(RealSubject realSubject) { this.realSubject = realSubject; } @Override public void request() { System.out.println("Before request"); realSubject.request(); System.out.println("After request"); } } // 使用 Subject subject = new StaticProxy(new RealSubject()); subject.request(); // JDK 动态代理 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before invocation"); Object result = method.invoke(target, args); System.out.println("After invocation"); return result; } } // 使用 Subject realSubject = new RealSubject(); Subject proxySubject = (Subject) Proxy.newProxyInstance( realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), new DynamicProxy(realSubject) ); proxySubject.request();

五、行为型模式

1. 策略模式

用途:定义一系列算法,将每个算法封装起来,并使它们可以互相替换

实现方式

  • 策略接口:定义算法的接口
  • 具体策略:实现策略接口
  • 上下文:使用策略的类

示例

// 策略接口 interface Strategy { int doOperation(int num1, int num2); } // 具体策略 class AddStrategy implements Strategy { @Override public int doOperation(int num1, int num2) { return num1 + num2; } } class SubtractStrategy implements Strategy { @Override public int doOperation(int num1, int num2) { return num1 - num2; } } class MultiplyStrategy implements Strategy { @Override public 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); } } // 使用 Context context = new Context(new AddStrategy()); System.out.println("10 + 5 = " + context.executeStrategy(10, 5)); context = new Context(new SubtractStrategy()); System.out.println("10 - 5 = " + context.executeStrategy(10, 5)); context = new Context(new MultiplyStrategy()); System.out.println("10 * 5 = " + context.executeStrategy(10, 5));

2. 观察者模式

用途:定义对象间的一种一对多依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新

实现方式

  • 主题:维护观察者列表,提供添加和删除观察者的方法
  • 观察者:定义更新接口
  • 具体主题:实现主题接口,维护状态
  • 具体观察者:实现观察者接口,响应主题的通知

示例

// 观察者接口 interface Observer { void update(); } // 主题接口 interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } // 具体主题 class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<>(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; notifyObservers(); } @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(); } } } // 具体观察者 class ConcreteObserver implements Observer { private ConcreteSubject subject; private int observerState; public ConcreteObserver(ConcreteSubject subject) { this.subject = subject; subject.registerObserver(this); } @Override public void update() { observerState = subject.getState(); System.out.println("Observer state updated: " + observerState); } } // 使用 ConcreteSubject subject = new ConcreteSubject(); ConcreteObserver observer1 = new ConcreteObserver(subject); ConcreteObserver observer2 = new ConcreteObserver(subject); subject.setState(10); subject.setState(20);

3. 责任链模式

用途:将请求的发送者和接收者解耦,使多个对象都有机会处理请求

实现方式

  • 处理器接口:定义处理请求的方法
  • 具体处理器:实现处理器接口,处理请求或传递给下一个处理器
  • 客户端:创建处理器链并发送请求

示例

// 处理器接口 interface Handler { void setNext(Handler next); void handleRequest(int request); } // 具体处理器 class ConcreteHandler1 implements Handler { private Handler next; @Override public void setNext(Handler next) { this.next = next; } @Override public void handleRequest(int request) { if (request >= 0 && request < 10) { System.out.println("ConcreteHandler1 handled request: " + request); } else if (next != null) { next.handleRequest(request); } } } class ConcreteHandler2 implements Handler { private Handler next; @Override public void setNext(Handler next) { this.next = next; } @Override public void handleRequest(int request) { if (request >= 10 && request < 20) { System.out.println("ConcreteHandler2 handled request: " + request); } else if (next != null) { next.handleRequest(request); } } } class ConcreteHandler3 implements Handler { private Handler next; @Override public void setNext(Handler next) { this.next = next; } @Override public void handleRequest(int request) { if (request >= 20 && request < 30) { System.out.println("ConcreteHandler3 handled request: " + request); } else if (next != null) { next.handleRequest(request); } } } // 使用 Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); handler1.setNext(handler2); handler2.setNext(handler3); // 发送请求 handler1.handleRequest(5); handler1.handleRequest(15); handler1.handleRequest(25); handler1.handleRequest(35);

六、设计模式最佳实践

1. 选择合适的设计模式

  • 根据问题选择:根据具体的问题场景选择合适的设计模式
  • 理解模式的意图:深入理解设计模式的意图和适用场景
  • 避免过度设计:不要为了使用设计模式而使用设计模式

2. 实现设计模式

  • 遵循设计原则:遵循 SOLID 原则
  • 保持简单:尽量保持设计模式的实现简洁明了
  • 考虑性能:在实现设计模式时考虑性能影响

3. 测试设计模式

  • 单元测试:测试设计模式的各个组件
  • 集成测试:测试设计模式在系统中的集成
  • 性能测试:测试设计模式的性能影响

七、实战案例

案例:电商系统中的设计模式

需求:构建一个电商系统,支持产品管理、订单管理、支付等功能

设计模式应用

  1. 单例模式:用于系统配置、数据库连接池等
  2. 工厂模式:用于创建不同类型的产品
  3. 建造者模式:用于构建复杂的订单对象
  4. 适配器模式:用于集成不同的支付系统
  5. 装饰器模式:用于添加产品的附加功能
  6. 策略模式:用于实现不同的支付策略
  7. 观察者模式:用于订单状态变化的通知
  8. 责任链模式:用于处理订单的审批流程

实现

// 单例模式:系统配置 public class SystemConfig { private static class ConfigHolder { private static final SystemConfig INSTANCE = new SystemConfig(); } private SystemConfig() {} public static SystemConfig getInstance() { return ConfigHolder.INSTANCE; } // 配置方法 public String getConfig(String key) { // 实现配置获取 return "config value"; } } // 工厂模式:产品工厂 interface ProductFactory { Product createProduct(); } class ElectronicProductFactory implements ProductFactory { @Override public Product createProduct() { return new ElectronicProduct(); } } class ClothingProductFactory implements ProductFactory { @Override public Product createProduct() { return new ClothingProduct(); } } // 建造者模式:订单建造者 class OrderBuilder { private Order order = new Order(); public OrderBuilder withId(long id) { order.setId(id); return this; } public OrderBuilder withCustomer(Customer customer) { order.setCustomer(customer); return this; } public OrderBuilder withProducts(List<Product> products) { order.setProducts(products); return this; } public Order build() { return order; } } // 策略模式:支付策略 interface PaymentStrategy { void pay(double amount); } class CreditCardPaymentStrategy implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("Paying " + amount + " using credit card"); } } class PayPalPaymentStrategy implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("Paying " + amount + " using PayPal"); } } // 观察者模式:订单状态观察者 interface OrderObserver { void update(Order order); } class EmailNotificationObserver implements OrderObserver { @Override public void update(Order order) { System.out.println("Sending email notification for order " + order.getId()); } } class SMSNotificationObserver implements OrderObserver { @Override public void update(Order order) { System.out.println("Sending SMS notification for order " + order.getId()); } }

结果

  • 系统设计清晰,易于维护和扩展
  • 各个组件职责明确,耦合度低
  • 系统具有良好的可测试性

八、总结

设计模式是软件开发中的重要工具,它们可以帮助我们构建更可维护、更可扩展的应用。通过合理地应用设计模式,我们可以提高代码的质量和可读性,减少重复代码,提高开发效率。

这其实可以更优雅一点。

希望这篇文章能帮助大家更好地理解和应用 Java 设计模式。如果你有任何问题,欢迎在评论区留言。


关于作者:我是 Alex,一个在 CSDN 写 Java 架构思考的暖男。喜欢手冲咖啡,养了一只叫"Java"的拉布拉多。如果我的文章对你有帮助,欢迎关注我,一起探讨 Java 技术的优雅之道。

http://www.jsqmd.com/news/603679/

相关文章:

  • LongCat-Image-Editn参数详解:UNet结构精简设计+CLIP文本编码器微调策略
  • Kilo推出企业智能体管理平台应对影子AI挑战
  • 暗黑3自动化工具终极指南:如何用智能技能宏提升游戏效率
  • 基于信息熵序数偏好法的多目标粒子群优化算法在电力系统储能选址定容中的研究与应用
  • 深度解析VeraGrid:电力系统开源仿真平台的架构革新与实践应用
  • 3个提升效率的Mac鼠标增强方案
  • 快速构建法律科技门户:使用快马AI十分钟生成qclaw官网原型
  • 别再死记硬背公式了!用Multisim仿真带你玩转OCL/OTL/BTL功放,手把手分析交越失真
  • ModTheSpire技术深度解析:Java字节码注入与游戏模组加载器架构剖析
  • 基于改进快速粒子群算法的IEEE33节点有源配电网动态无功优化软件介绍
  • Go语言学习之对象关系映射GORM
  • 基于蒙特卡洛法的电动汽车无序接入对配电网影响的潮流计算和优化
  • 程序员的中年危机:技术更新太快还是我们太慢?
  • Amadeus的知识库 | RAG 场景下大模型有记忆了检索系统却犯了难?—— 重中之重是搞清问题重写策略!
  • 约束优化实战:从罚函数到乘子法的算法演进与代码实现
  • 终极Windows 11优化指南:如何用Win11Debloat一键清理系统臃肿
  • 华硕笔记本终极性能控制指南:G-Helper完整使用教程
  • 项目实战之评论情感分析模型——基于Bert(含任务头)
  • 基于51单片机的扫地小车设计与实现:寻迹避障、智能往返清扫功能详解
  • 涨薪技术|Prometheus中配置Alertmanager
  • openpilot技术实战指南:从问题诊断到解决方案的系统方法论
  • Spring Boot 性能优化最佳实践:构建高性能应用
  • Zabbix监控Docker化部署避坑指南:从镜像版本选择到安全加固的完整配置
  • 别再傻傻分不清!Quectel RX500U 5G模组的‘网卡模式’和‘路由模式’到底怎么选?
  • Uni-App水印相机避坑指南:解决canvas绘制白屏、iOS拍照失败和权限获取的那些坑
  • 什么是埋点测试,app埋点测试怎么做?
  • 09-多模型配置指南
  • C++ 移动构造与移动赋值:类成员变量处理方式
  • DFS:带重复项的全排列,程序运行全流程解析
  • 【研报287】小马智行深度报告:Robotaxi赛道的竞争格局