面向对象设计的七大设计原则

# 面向对象设计的七大设计原则

在我们探讨如何创建健壮且可维护的面向对象系统时,有一些原则可以为我们提供指导。这些原则可以帮助我们理解如何最好地组织我们的类和对象,以实现高效、模块化和可扩展的设计。在本篇文章中,我们将探讨这些原则,以及如何在我们的设计中应用它们。

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

单一职责原则是指一个类应该只有一个引起变化的原因。这可能听起来有些抽象,但实际上,这是一个非常强大的概念。当我们设计一个类时,我们通常被诱惑去让它做更多的事情。然而,当一个类的职责过多时,它就会变得复杂且难以维护。

例如,我们可能有一个User类,它负责管理用户的信息,如用户名、密码等。然而,如果我们还让这个类负责验证用户、管理用户的登录状态、处理用户的购物车等,那么这个类就会变得非常复杂。

通过确保每个类只有一个职责,我们可以降低类的复杂性,使其更易于理解和维护。此外,当需求发生变化时,我们只需要修改负责该职责的类,而不会影响到其他的代码。

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

开放封闭原则是指软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这个原则的主要思想是,我们应该能够在不修改现有代码的情况下,添加新的功能。

这个原则的实现通常依赖于接口和抽象类。通过定义接口或抽象类,我们可以定义一个稳定的API,然后通过继承和实现这些接口或抽象类来添加新的功能。

例如,我们可能有一个PaymentProcessor接口,定义了处理支付的方法。然后,我们可以创建CreditCardPaymentProcessorPaypalPaymentProcessor类来实现这个接口。当我们需要添加一个新的支付方式时,我们只需要创建一个新的类来实现PaymentProcessor接口,而不需要修改现有的代码。

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

里氏替换原则是指如果一个程序使用一个基类的对象,那么它应该能够使用一个子类的对象而不产生任何错误或异常,且不需要修改这个程序的正确性。

这个原则的主要思想是,子类应该能够完全替代它们的基类。这意味着,我们在设计子类时,应该确保它们不会违反基类的行为。

例如,我们可能有一个Rectangle类,有widthheight两个属性,和一个area方法用于计算面积。然后,我们创建了一个Square类继承自Rectangle,并重写了widthheight的setter方法,使得它们总是设置为相同的值。这看起来似乎是合理的,因为在数学上,正方形是一种特殊的矩形。然而,如果我们有一段代码是这样的:

Rectangle r = new Rectangle();
r.setWidth(5);
r.setHeight(4);
assert r.area() == 20;

然后我们用Square替换Rectangle

Rectangle r = new Square();
r.setWidth(5);
r.setHeight(4);
assert r.area() == 20; // 这会失败,因为面积是16,而不是20

我们会发现,尽管SquareRectangle的子类,但它不能完全替代Rectangle。因此,它违反了里氏替换原则。

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

接口隔离原则指的是客户端不应该依赖它不需要的接口。换句话说,一个类不应该被强制实现它不需要的方法。这个原则鼓励我们创建精细粒度的接口,而不是创建大而全的接口。

例如,我们可能有一个Worker接口,定义了workeat两个方法。然后,我们有一个Robot类实现了这个接口。然而,Robot并不需要吃东西,所以eat方法对它来说是没有意义的。这就违反了接口隔离原则。

为了遵循接口隔离原则,我们可以将Worker接口拆分为两个接口:WorkableEatableWorkable接口定义了work方法,Eatable接口定义了eat方法。然后,Robot只需要实现Workable接口,而不需要实现Eatable接口。

依赖反转原则 (Dependency Inversion Principle, DIP)

依赖反转原则是指高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。简单来说,要依赖于抽象(接口或抽象类),不要依赖于具体类。

这个原则的主要思想是,我们应该尽可能地使我们的代码解耦。当我们的代码依赖于具体的实现时,它就会变得脆弱且难以改变。然而,当我们的代码依赖于抽象时,我们就可以很容易地更换不同的实现,而不需要修改依赖于这些抽象的代码。

例如,我们可能有一个UserRepository类,它负责从数据库中获取用户。然后,我们有一个UserService类,它依赖于UserRepository来获取用户。这样,当我们需要从不同的数据源获取用户时(比如从网络或内存),我们就需要修改UserService类。然而,如果UserService依赖于一个抽象的UserRepository接口,那么我们就可以通过创建新的UserRepository实现来更换数据源,而不需要修改UserService类。

合成复用原则 (Composition Over Inheritance, COI)

合成复用原则是指尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的。这个原则的主要思想是,组合和聚合可以提供更大的灵活性,降低类与类之间的耦合度,一个类的变动对其他类造成的影响相对较少。

例如,我们可能有一个Bird类和一个Airplane类,它们都需要飞行的功能。我们可以创建一个Flyable接口,然后让BirdAirplane都实现这个接口。这样,BirdAirplane就可以复用Flyable接口的飞行功能,而不需要通过继承来复用这个功能。

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

迪米特法则也被称为最少知道原则,它指的是一个对象应该对其他对象有最少的了解。换句话说,一个类应该只和它的直接依赖关系交互,不和远程的类交互。

这个原则的主要思想是,我们应该尽可能地降低类与类之间的耦合度。当一个类知道太多其他类的信息时,它就会变得复杂且难以改变。然而,当一个类只和它的直接依赖关系交互时,它就会变得更加独立且易于理解和维护。

例如,我们可能有一个User类,一个Order类,和一个Product类。User类有一个placeOrder方法,需要使用OrderProduct类。然而,如果placeOrder方法直接操作Product类,那么User类就会知道Product类的太多信息,这就违反了迪米特法则。为了遵循迪米特法则,我们可以让placeOrder方法只接受一个Order对象,然后让Order对象负责处理Product对象。

结语

这些原则并不是铁律,而是一种指导思想,可以帮助我们设计出高质量的面向对象系统。在实际的开发过程中,我们需要根据实际的需求和场景,灵活地运用这些原则。

例如,如果我们正在创建一个非常简单的系统,那么严格遵循SOLID原则可能会导致我们的代码变得过于复杂。在这种情况下,我们可能会选择违反一些原则,以便保持我们的代码简单和易于理解。

另一方面,如果我们正在创建一个需要处理复杂业务逻辑和多变需求的大型系统,那么遵循SOLID原则可以帮助我们设计出更加灵活、可维护、可扩展的系统。在这种情况下,我们可能会选择严格遵循一些SOLID原则。

总的来说,SOLID原则是一种工具,而不是目标。我们应该理解这些原则背后的目的和意义,然后在适当的时候使用它们,而不是盲目地遵循它们。

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

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

相关文章

Pyth 预言机: 它们如何影响Hover?

所有链上借贷市场都使用一种称为“oracle(预言机)”的服务,为dApp提供代币定价。Oracle是一个数据系统,将链下信息(例如KuCoin上的BTC/USDT价格)传递到链上合约。从那里,应用程序可以支付一小笔…

MAVEN(1)

分模块开发与设计 分模块开发意义 将原始模块按照功能拆分成若干个子模块,方便模块间相互调用,接口共享 步骤示例 这里以之前开发的SpringMVC_ssm中的domain模块为例 第一步、创建Maven模块 父项改为none,文件存储位置需要做出相应调整 …

MySQL基础(三)-学习笔记

一.innodb引擎: 1). 表空间:表空间是InnoDB存储引擎逻辑结构的最高层,启用了参数 innodb_file_per_table(在 8.0版本中默认开启) ,则每张表都会有一个表空间(xxx.ibd),一个mysql实例可以对应多个…

Revisiting image pyramid structure for high resolution salient object detection

accv2022的技术,在我测评的数据集上确实要明显好于basnet,rembg等一众方法。 1.Introduction 使用LR数据集训练的方法通过调整输入尺寸可以在HR图像上产生不错的结果。本文主要关注仅使用LR数据集进行训练以产生高质量的HR预测。HR的有效感受野ERFs和LR…

QT学习日记 | 信号与槽

目录 前言 一、初始信号与槽 1、信号与槽的本质 2、信号与槽的使用 3、内置信号、内置槽函数与自定义信号、自定义槽函数 (1)文档查询 (2)自定义信号与内置槽函数的使用 4、信号与槽函数关联关系 5、带参数的信号与槽函数…

计算机毕业设计 | springboot 多功能商城 购物网站(附源码)

1, 概述 国家大力推进信息化建设的大背景下,城市网络基础设施和信息化应用水平得到了极大的提高和提高。特别是在经济发达的沿海地区,商业和服务业也比较发达,公众接受新事物的能力和消费水平也比较高。开展商贸流通产业的信息化…

Java和JavaScript的区别与联系

引言 Java是一种由Sun Microsystems(现在是Oracle公司)开发的面向对象编程语言,最初于1995年发布。Java被设计为一种跨平台的语言,可以在多个操作系统上运行,这是其广泛应用的重要原因之一。Java具有丰富的标准库和第三…

常见分类网络的结构

VGG16 图片来自这里 MobilenetV3 small和large版本参数,图片来着这里 Resnet 图片来自这里

AutoDL使用conda运行pytorch、dgl

环境配置要是出现兼容问题还是挺繁琐的。所以这里记录下成功的配置情况。 conda create --name Test python3.9 # 构建一个虚拟环境 conda init bash && source /root/.bashrc # 更新bashrc中的环境变量 conda activate Test # 切换到该虚拟环境 pip install torch…

windows安装oracle之后怎么连接使用

目录 1.打开SQl Developer 2.选择JDK 3.登录 4.创建表空间,用户 安装oracle的详细教程 WINDOWS安装Oracle11.2.0.4-CSDN博客 1.打开SQl Developer 找到 SQl Developer 2.选择JDK 根据你安装的oracle版本,因为我的oracle是安装的32位的,所以这里jdk也要选择32位 选择到ja…

私募证券基金动态-23年12月报

成交量:12月日均7,696.93亿元 2023年12月A股两市日均成交7,696.93亿元,环比下降12.39%、同比下降2.26%。12月整体21个交易日,无单日交易日成交金额过万亿,单日交易日最低成交金额为6,122.84亿元(12月25日)…

【Linux】进程通信——共享内存+消息队列+信号量

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:题目解析 🌎推荐文章:【LeetCode】winter vacation training 目录 👉🏻共享内存👉🏻关…

测试用例的设计(超详细)

🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号:互联网杂货铺,回复1 ,免费获取软件测试全套资料,资料在手,薪资嘎嘎涨 1. 测试用例的概念 软件测试人员向被测试系统提供的一…

MySQL窗口函数--lead()函数

lead()函数: 查询当前行向下偏移n行对应的结果 该函数有三个参数:第一个为待查询的参数列名,第二个为向下偏移的位数,第三个参数为超出最下面边界的默认值。 如下代码: 查询向下偏移 2 位的年龄 SELECT user_id,user…

学习Android的第一天

目录 什么是 Android? Android 官网 Android 应用程序 Android 开发环境搭建 Android 平台架构 Android 应用程序组件 附件组件 Android 第一个程序 HelloWorld 什么是 Android? Android(发音为[ˈnˌdrɔɪd],非官方中文…

Linux 驱动开发基础知识——总线设备驱动模型(八)

个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS 🐼本文由…

SAP SD出库单部分开票后无法继续开票

SAP SD出库单部分开票后无法继续开票。 凭证 80051268 没有包含任何带有未清数量的项目 消息编号 VF171 诊断 凭证80051268不包含可以转换到开票类型中的项目。 系统响应 系统拒绝任何后续处理。 步骤 请检查选择的销售和分销凭证。 除了修改VBUP的相关字段,还有…

服务器未启动而端口进程仍在运行如何查看并杀死

首先登录服务器然后查看当前监听的端口: sudo netstat -tuln比如这里的8080,我们此时并未启动服务器,但是它却正在运行,这会导致服务器刚启动就秒挂。如果没有日志的话会让人有点疑惑,这种情况可能是之前运行了该进程…

外汇天眼:SIX推出了新的SIX参考利率加密货币和SIX实时加密货币指数

全球金融信息提供商SIX今天宣布推出新的SIX参考利率加密货币和SIX实时加密货币指数。新的SIX参考利率加密货币指数和SIX实时加密货币指数涵盖了主要的加密资产比特币(BTC)和以太坊(ETH),为市场及其表现提供了全面的快照…

C/C++ - 函数模板

目录 函数模板基础 函数模板定义 函数模板实例 函数模板调用 函数模板本质 模板函数特化 模板参数限定 默认模板参数 多个模板参数 非类型模板参数 函数模板拓展 模板参数匹配规则 函数模板基础 函数模板定义 使用 template <typename T>​​​​​ 或 templ…