Java 设计模式 详解

devtools/2024/11/20 17:51:20/

在Java开发中,设计模式是一种常见的、成熟的解决方案,用于应对特定的设计问题和复杂性管理。以下是一些常用的设计模式,它们可以分为三类:创建型模式、结构型模式和行为型模式。

一、创建型模式

创建型模式主要负责对象的创建,能够将对象的创建过程与使用过程分离,避免过度依赖具体类的构造。

  1. 单例模式(Singleton Pattern)

    • 确保一个类只有一个实例,并提供一个全局访问点。
    • 使用场景:数据库连接、配置管理、线程池等。
  2. 工厂方法模式(Factory Method Pattern)

    • 定义一个接口用于创建对象,但让子类决定实例化哪一个类。工厂方法将实例化过程延迟到子类。
    • 使用场景:需要创建复杂对象时,可以通过不同的工厂来灵活生产。
  3. 抽象工厂模式(Abstract Factory Pattern)

    • 提供一个创建一系列相关或依赖对象的接口,而无需指定它们的具体类。
    • 使用场景:产品族的创建,如一整套UI组件(按钮、文本框等)等。
  4. 建造者模式(Builder Pattern)

    • 将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
    • 使用场景:构建复杂对象,比如包含多种属性的对象或多步构建流程。
  5. 原型模式(Prototype Pattern)

    • 通过复制现有实例来创建新对象,而不是通过实例化。
    • 使用场景:当创建对象的成本较高,且我们可以复制已有对象来生成新实例时。

二、结构型模式

结构型模式用于处理类或对象之间的关系,通过继承或组合的方式使得系统更具灵活性。

  1. 适配器模式(Adapter Pattern)

    • 将一个类的接口转换成客户端期望的另一个接口,使得原本不兼容的类可以一起工作。
    • 使用场景:系统需要使用新旧接口兼容的类。
  2. 装饰器模式(Decorator Pattern)

    • 动态地给对象添加额外的职责,而不改变其结构。
    • 使用场景:扩展类的功能,而无需创建子类。
  3. 代理模式(Proxy Pattern)

    • 提供一个代理对象来控制对原对象的访问,保护原对象或增加额外操作。
    • 使用场景:权限控制、对象的延迟加载、缓存等。
  4. 外观模式(Facade Pattern)

    • 为子系统中的一组接口提供一个统一的接口,简化对复杂子系统的使用。
    • 使用场景:简化客户端调用多个复杂的子系统。
  5. 享元模式(Flyweight Pattern)

    • 通过共享技术有效地支持大量的细粒度对象,减少内存开销。
    • 使用场景:需要大量重复对象时,如文本处理中的字符对象。
  6. 组合模式(Composite Pattern)

    • 将对象组合成树形结构以表示“部分-整体”的层次结构,客户端可以统一对待单个对象和组合对象。
    • 使用场景:处理树形结构的数据,如文件目录。

三、行为型模式

行为型模式关注对象之间的协作和职责分配,帮助处理对象之间的交互。

  1. 策略模式(Strategy Pattern)

    • 定义一系列算法,将它们封装起来,使它们可以互相替换,客户端可以灵活地选择算法。
    • 使用场景:多个算法可以互换,例如不同的排序策略。
  2. 模板方法模式(Template Method Pattern)

    • 在父类中定义一个算法的骨架,而将一些步骤延迟到子类中。
    • 使用场景:一些操作步骤不可改变,但细节不同。
  3. 观察者模式(Observer Pattern)

    • 定义对象间的一对多依赖关系,当一个对象状态发生改变时,所有依赖它的对象都能自动更新。
    • 使用场景:订阅-发布系统,如新闻订阅、事件处理。
  4. 责任链模式(Chain of Responsibility Pattern)

    • 让多个对象有机会处理请求,将这些对象串成一条链,并沿着这条链传递请求。
    • 使用场景:权限过滤、事件处理链。
  5. 命令模式(Command Pattern)

    • 将请求封装成一个对象,以便使用不同的请求、队列、日志等来进行参数化。
    • 使用场景:事务管理、日志请求恢复、撤销操作。
  6. 状态模式(State Pattern)

    • 允许对象在内部状态改变时改变它的行为,使得对象看起来改变了其类。
    • 使用场景:状态机设计,如电梯系统、自动售货机。
  7. 备忘录模式(Memento Pattern)

    • 在不破坏封装的前提下,捕获对象的内部状态,以便在将来恢复。
    • 使用场景:撤销操作、恢复状态。
  8. 迭代器模式(Iterator Pattern)

    • 提供一种方法顺序访问集合中的元素,而无需暴露集合的内部表示。
    • 使用场景:集合遍历,Java的Iterator就是此模式的实现。
  9. 中介者模式(Mediator Pattern)

    • 定义一个对象来封装一组对象之间的交互关系,避免对象之间的直接引用,使得耦合松散。
    • 使用场景:GUI控件之间的交互,聊天应用中的消息路由。
  10. 解释器模式(Interpreter Pattern)

    • 为某个语言定义文法表示,并提供一个解释器来处理这些文法。
    • 使用场景:SQL解析、正则表达式解释、脚本语言处理。

总结

在Java开发中,不同的设计模式可以帮助我们应对不同的设计挑战,从而实现高效、灵活且易维护的系统结构。在实际应用中,通常会结合多种模式来满足复杂的需求,选择合适的模式可以大大提升代码的可读性和复用性。


http://www.ppmy.cn/devtools/135541.html

相关文章

51单片机应用开发(进阶)---模块化编程

实现目标 1、掌握.h 文件的格式、extern 的用法; 2、握模块化编程方法步骤; 3、具体实现:(1)提供一个C文件,将其按照功能模块进行模块化。 一、为什么要进行模块化编程? 传统的编程方式&…

如何在项目中用elementui实现分页器功能

1.在结构部分复制官网代码&#xff1a; <template> 标签: 这是 Vue 模板的根标签&#xff0c;包含所有的 HTML 元素和 Vue 组件。 <div> 标签: 这是一个普通的 HTML 元素&#xff0c;包裹了 el-pagination 组件。它没有特别的意义&#xff0c;只是为了确保 el-pagi…

Electron教程1-初学入门

玩转Electron Electron 是什么注意事项环境安装安装 vscode安装 git 第一个实例第二个实例第二个实例解读 总结问题解答 Electron 是什么 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个…

C++小白实习日记——Day 5 gitee怎么删文件,测试文件怎么写循环

昨晚一直内耗&#xff0c;一个程序写了三天写不出来&#xff0c;主要是耗时太多了&#xff0c;老板一直不满意。想在VScode上跑一下&#xff0c;昨晚一直报错。今天来公司重新搞了一下&#xff0c; 主要工作有&#xff1a; 1&#xff0c;读取当前时间用tscns 2&#xff0c;输…

036集——查询CAD图元属性字段信息:窗体显示(CAD—C#二次开发入门)

提取CAD图元所有属性字段&#xff0c;通过窗体显示&#xff0c;效果如下&#xff1a;&#xff08;curve改为entity&#xff09; 代码如下&#xff1a; public void 属性查询() {List<Curve> ents Z.db.SelectEntities<Curve>();if (ents is null ||ents.Cou…

vscode 关闭绑定元素 隐式具有“any”类型这类错误

在vue的项目里面&#xff0c;经常看到any类型的报错&#xff0c;真的很烦的 在tsconfig.json中配置以下参数 “noImplicitAny”: false 就可以了 出现类型“never”上不存在属性“userName”。ts-plugin(2339) 配置该参数 modeuleResolution : node "compilerOptions&qu…

优化装配,提升品质:虚拟装配在汽车制造中的关键作用

汽车是各种零部件的有机结合体&#xff0c;因此汽车的装配工艺水平和装配质量直接影响着汽车的质量与性能。在汽车装配过程中&#xff0c;经常会发生零部件间干涉或装配顺序不合理等现象&#xff0c;且许多零部件制造阶段产生的质量隐患要等到实际装配阶段才能显现出来&#xf…

[Leetcode小记] 3242. 设计相邻元素求和服务

题目&#xff1a; 代码&#xff1a; class NeighborSum {private int n;private int[][] grid;private int[][] adjacent_sum;private int[][] diagonal_sum;private int[][] index_map;public NeighborSum(int[][] grid) {this.gridgrid;ngrid.length;adjacent_sumnew int[n]…