java设计原则和具体应用

在Java设计中,遵循一些核心的设计原则可以极大地提高代码的可读性、可维护性、可扩展性和复用性。以下是一些关键的Java设计原则:

1. 单一职责原则(Single Responsibility Principle, SRP)

原则说明:一个类应该仅有一个引起它变化的原因,即一个类应该只负责一项职责。如果一个类承担的职责过多,就等于把这些职责耦合在一起了,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。

应用示例:在在线学习平台中,CourseManagementInterface仅处理与课程管理相关的功能(添加课程、更新课程信息等),而用户信息管理则由UserManagementInterface负责。

2. 接口隔离原则(Interface Segregation Principle, ISP)

原则说明:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。使用多个专门的接口比使用单一的总接口要好。

应用示例:在多功能设备中,如打印机同时具备打印、扫描和传真功能,将这些功能拆分为PrinterInterfaceScannerInterfaceFaxInterface,使得只需要打印功能的客户端不必关心扫描或传真的实现,降低了耦合性。

3. 依赖倒置原则(Dependency Inversion Principle, DIP)

原则说明:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

应用示例:在电商系统中,订单处理模块不直接依赖具体的数据库实现,而是依赖于抽象的数据访问接口DataAccessInterface。这种设计允许系统在不修改订单模块的情况下更换数据库实现,提高了系统的灵活性和可扩展性。

4. 高内聚低耦合原则(High Cohesion and Low Coupling)

原则说明:接口内的方法应紧密相关,接口间的依赖应最小化。高内聚指的是类内部的方法和属性之间应该高度相关,共同完成一个特定的任务;低耦合指的是类与类之间应该尽可能减少直接的依赖关系,以提高系统的灵活性和可维护性。

应用示例:视频游戏中的角色类可以通过MovableAttackableTalkable等接口分离不同的行为,提升了模块的内聚性和系统的可维护性。

5. 可扩展性原则(Extensibility Principle)

原则说明:接口设计应考虑未来可能的变化,易于添加新功能而不影响既有功能。

应用示例:在事件处理系统中,初始设计时包括onClick()onDrag()方法。通过采用观察者模式,可以在不修改现有代码的基础上,添加对新事件如滚动或双击的处理。

6. 开闭原则(Open-Closed Principle, OCP)

原则说明:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。即软件实体应该可以通过扩展来实现变化,而不是通过修改已有的代码来实现变化。

应用示例:使用抽象类和接口来实现开闭原则,允许在不修改现有代码的情况下添加新的功能或行为。

7. 里氏替换原则(Liskov Substitution Principle, LSP)

原则说明:如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。

应用示例:在面向对象设计中,确保子类可以无缝地替换掉父类,而不会导致程序的行为发生改变。

这些设计原则在Java及其他面向对象编程语言中都被广泛采用,它们为构建高质量、可维护、可扩展的软件系统提供了坚实的基础。


在软件设计中,设计原则的应用是确保代码质量、可维护性和可扩展性的关键。以下是对几个核心设计原则的应用解释:

1. 单一职责原则(Single Responsibility Principle, SRP)

定义:一个类应该只负责一项职责。

应用

  • 分离关注点:确保每个类只关注一个主题或功能领域。例如,如果一个类既处理用户输入又负责数据存储,则应将其拆分为两个类:一个处理输入,另一个处理存储。
  • 高内聚低耦合:通过遵循单一职责原则,可以提高类的内聚性并降低类之间的耦合度,从而增强系统的可维护性和可扩展性。

2. 开放/封闭原则(Open-Closed Principle, OCP)

定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。

应用

  • 抽象与接口:使用抽象类或接口定义稳定的接口,让子类或具体实现类通过扩展这些接口来应对变化。这样,当需要添加新功能时,只需添加新的子类或实现类,而无需修改现有的代码。
  • 策略模式:策略模式是实现开放/封闭原则的一种常用设计模式,它定义了一系列算法,并将它们封装起来,使它们可以互相替换。

3. 里氏替换原则(Liskov Substitution Principle, LSP)

定义:子类对象必须能够替换掉它们的基类对象被使用。

应用

  • 保持接口兼容:子类在扩展基类时,应确保不会破坏基类的行为契约。即,任何使用基类对象的地方,都可以透明地使用子类对象替换,而不会产生错误或异常。
  • 合理设计继承:在设计继承结构时,要仔细考虑哪些方法是基类必须提供的,哪些方法是子类可以扩展或覆盖的。

4. 依赖倒置原则(Dependency Inversion Principle, DIP)

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。

应用

  • 面向接口编程:通过接口或抽象类来定义依赖关系,而不是具体的实现类。这样,当实现类发生变化时,只要接口保持不变,依赖这些接口的高层模块就不会受到影响。
  • 减少耦合:依赖倒置原则有助于降低模块之间的耦合度,提高系统的灵活性和可维护性。

5. 接口隔离原则(Interface Segregation Principle, ISP)

定义:客户端不应该依赖它不使用的接口;一个类对另一个类的依赖应该建立在最小的接口上。

应用

  • 定义小而专注的接口:将大而全的接口拆分成多个小而专注的接口,确保每个接口都尽可能简单和明确。这样,客户端只需实现它需要的接口,而无需被迫实现它不需要的方法。
  • 使用适配器模式:在某些情况下,可以使用适配器模式来实现接口隔离原则。适配器模式允许一个类只关注于它需要使用的接口方法,而不必实现所有方法。

6. 合成/聚合复用原则(Composite/Aggregate Reuse Principle, CARP)

定义:尽量使用合成/聚合的方式,而不是使用继承来达到复用的目的。

应用

  • 组合与聚合:通过组合或聚合的方式将多个对象组合成一个更大的对象,以实现功能的复用。这种方式比继承更加灵活和可扩展,因为它不会破坏类的封装性,也不会导致类之间的紧耦合。
  • 减少继承:虽然继承是实现代码复用的一种有效方式,但过度使用继承会导致类之间的耦合度增加,且难以维护。因此,在可能的情况下,应尽量使用组合或聚合的方式来替代继承。

7. 迪米特法则(Law of Demeter, LoD)

定义:一个对象应该对其他对象保持最少的了解。

应用

  • 减少依赖:在设计系统时,应尽量减少对象之间的直接依赖关系。可以通过引入中介者、外观模式等设计模式来降低对象之间的耦合度。
  • 封装细节:将对象内部的实现细节封装起来,只对外提供必要的接口或方法。这样,其他对象在调用这些接口或方法时,就无需关心对象内部的实现细节。

以上设计原则在软件设计中的应用,有助于创建出清晰、可维护、可扩展的代码结构,提高软件的整体质量。

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

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

相关文章

科大讯飞语音转写demo go语言版

上传了一个语音文件,识别效果。 package audioimport ("bytes""crypto/hmac""crypto/md5""crypto/sha1""encoding/base64""encoding/json""fmt""io/ioutil""net/http"…

【图文详解】Spring是如何解决循环依赖的?

Spring是如何解决循环依赖的呢? 很多小伙伴在面试时都被问到过这个问题,刷到过这个题的同学马上就能回答出来:“利用三级缓存”。面试官接着追问:“哪三级缓存呢?用两级行不行呢?” 这时候如果没有深入研究…

Vs2022+QT+Opencv 一些需要注意的地方

要在vs2022创建QT项目,先要安装一个插件Qt Visual Studio Tools,根据个人经验选择LEGACY Qt Visual Studio Tools好一些,看以下内容之前建议先在vs2022中配置好opencv,配置方式建议以属性表的形式保存在硬盘上。 设置QT路径 打开v…

清华计算几何-算法LowBound和ConvexHull(凸包)-GrahamScan

算法复杂度最低界限LowBound 算法求解复杂度是否存在一个最低界限,有时候想尽一切办法优化一个算法,去优化其复杂度,比如 清华计算几何-ConvexHull(凸包)-求极点InTriangle/ToLeft Test-CSDN博客 清华计算几何-ConvexHull(凸包)-求极边_计…

DeFi革命:揭秘去中心化金融的核心技术与实操指南

目录 DeFi(去中心化金融)综述 基本特点 第一,DeFi 是无许可的金融 第二,DeFi 是无门槛的金融 第三,DeFi 是无人驾驶的金融 典型商业模式 闪电贷 MakerDAO 面临的挑战 DeFi技术要点 椭圆曲线签名 EIP-712:…

模拟依赖关系和 AI 是Vue.js测试的下一个前沿领域

Vue.js 是一个流行的 JavaScript 框架,因此,确保其组件按预期工作至关重要:有效,更重要的是,可靠。模拟依赖项是最有效的测试方法之一,我们将在本文中发现。 模拟依赖项的必要性 模拟依赖项是一种对测试施加…

个人定制化形象生成,FaceChain最新模型部署

FaceChain是阿里巴巴达摩院推出的一个开源的人物写真和个人数字形象的AI生成框架。 FaceChain利用了Stable Diffusion模型的文生图功能,并结合人像风格化LoRA模型训练及人脸相关感知理解模型,将输入的图片进行训练后推理输出生成个人写真图像。 FaceCh…

基于深度学习的文本自监督学习

基于深度学习的文本自监督学习(Self-Supervised Learning, SSL)是一种利用未标注文本数据通过预任务进行训练,以学习有用的文本表示的方法。自监督学习在自然语言处理(NLP)领域中取得了显著的成果,如BERT、…

Live555源码阅读笔记:哈希表的实现(C++)

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

算法日记day 20(中序后序遍历序列构造二叉树|最大、合并、搜索二叉树)

一、中序后序序列构造二叉树 题目: 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,…

使用SpringEvent解决WebUploader大文件上传解耦问题

目录 前言 一、SpringEvent涉及的相关组件 1、 事件(Event) 2、事件监听器 3、事件发布器 二、WebUploader大文件处理的相关事件分析 1、事件发布的时机 2、事件发布的代码 三、事件监听器及实际的业务处理 1、文件上传处理枚举 2、文件上传监…

pthread多线程

pthread库是linux系统的多线程库。上次写完longjmp和多线程的例子。就想用系统的真线程库改写一下读写线程的例子来和大家分享。真线程库应该比自己写的功能更完善,代码也更容易写吧!… … 说到这里。我不知道接下来说什么了… …。也许是自己对多线程库…

ConstraintLayout实现原理分析

ConstraintLayout 是 Android 支持库中提供的一个非常强大的布局管理器,它允许开发者创建复杂的界面布局,并提供了比传统布局更多的灵活性。在 ConstraintLayout 中,视图之间可以通过约束来定义其位置关系,从而使得布局更加动态和…

Python+selenium web自动化测试知识点合集2

选择元素 对于百度搜索页面,如果我们想自动化输入“selenium”,怎么做呢? 这就是在网页中,操控界面元素。 web界面自动化,要操控元素,首先需要 选择 界面元素 ,或者说 定位 界面元素 就是 先…

OD C卷 - 电脑病毒感染

电脑病毒感染 (200) 一个局域网内有n台电脑,编号为 1 -> n,电脑之间病毒感染时间用 t 表示;现在网络内已有一台电脑被病毒感染,求其感染所有其他电脑最少的时间,若最后有电脑不会被感染&…

URL重写

目录 步骤1 规则语法 Nginx URL重写规则语法 Apache URL重写规则语法 步骤2 规则配置 Apache URL重写规则配置 启用mod_rewrite模块 配置.htaccess文件 编写重写规则 测试重写规则 Nginx URL重写规则配置 配置server或location块 测试重写规则 步骤1 规则语法 Ngin…

如何使用Redis实现一个缓存策略

使用Redis实现一个缓存策略,主要涉及到数据的存储、读取、更新以及失效处理等方面。下面我将详细介绍如何使用Redis来设计和实现一个基本的缓存策略。 1. 确定缓存的数据结构和键命名规则 首先,你需要决定使用Redis中的哪种数据结构来存储缓存数据&…

解决在from pyhdf.SD import SD,SDC时No module named “hdfext“

文章内容仅用于自己知识学习和分享,如有侵权,还请联系并删除 :) 1. 错误原因: 参考了多个博主的解决办法,结合自己的尝试,发现造成这个问题的主要原因是numpy版本太高 2. 解决方法 方法1&…

Day.31 | 1049.最后一块石头的重量II 494.目标和 474.一和零

1049.最后一块石头的重量II 要点&#xff1a;思路与分割等和子集很类似&#xff0c;把总数分成和最接近的两堆&#xff0c;然后用01背包的套路解答 class Solution { public:int lastStoneWeightII(vector<int>& stones) {int sum 0;for (int i : stones)sum i;i…

C++客户端Qt开发——界面优化(QSS)

1.QSS 如果通过QSS设置的样式和通过C代码设置的样式冲突&#xff0c;则QSS优先级更高 ①基本语法 选择器{属性名&#xff1a;属性值; } 例如&#xff1a; QPushButton {color: red; } 1>指定控件设置样式 #include "widget.h" #include "ui_widget.h&qu…