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

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

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

单一职责原则 (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原则是一种工具,而不是目标。我们应该理解这些原则背后的目的和意义,然后在适当的时候使用它们,而不是盲目地遵循它们。

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

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

相关文章

centos7安装mysql5.7 或者mysql8

1、centos7安装mysql8 mysql官网 https://dev.mysql.com/downloads/mysql/ 示例2个版本的下载地址 #5.7.30下载地址 wget https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.30-1.el7.x86_64.rpm-bundle.tar #8.0.22下载地址 wget https://cdn.mysql.com/archives/mysql-8…

Maya------布尔 圆形圆角组件

17. maya常用命令7.布尔 圆形圆角组件_哔哩哔哩_bilibili 选中一个模型,再按shift加选另外一个模型 圆形圆角命令

PVE安装后报错:NO IOMMU Detected解决办法

1、首先在BIOS中确定图形界面卡,打开了VT-D功能。 2、修改grub vim /etc/default/grub 找到:GRUB_CMDLINE_LINUX_DEFAULT"quiet" 然后修改为 GRUB_CMDLINE_LINUX_DEFAULT"quiet intel_iommuon" 3、使用命…

华擎B660 主板 怎么设置打开来电自启功能?

环境: 华擎B660 钢铁传奇 1700 : Intel B660 问题描述: 华擎B660 主板 怎么设置打开来电自启功能? 解决方案: 1.前往-高级- 芯片组配置 2.往下划找到交流 /电源断电恢复 选择电源故障后的电源状态。如果选择 [关机]&#x…

mapbox gl 测量

一、代码 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>Measure distances</title> <meta name"viewport" content"initial-scale1,maximum-scale1,user-scalableno"> <link hre…

Typora导出html文件图片自动转换成base64

Typora导出html文件图片自动转换成base64 一、出现问题二、解决方案三、编码实现3.1.创建Java项目3.2.代码3.3.打包成Jar包 四、如何使用endl 一、出现问题 typora 导出 html 的时候必须带有原图片&#xff0c;不方便交流学习&#xff0c;文件太多显得冗余&#xff0c;只有将图…

【vim 学习系列文章 3.2 -- vim 删除 空格】

文章目录 vim 删除行尾空格 vim 删除行尾空格 在代码开发的过程中&#xff0c;经常会遇到行尾有空格的现象&#xff0c;如下&#xff1a; 我们可以在 .vimrc 中通过map 命令来映射删除行尾空格的快捷键&#xff0c;如下&#xff1a; map d<space> :%s/\s*$//g <cr…

Spring速成(一)

文章目录 Spring速成&#xff08;一&#xff09;1&#xff0c;课程介绍1.1 为什么要学?1.2 学什么?1.3 怎么学? 2&#xff0c;Spring相关概念2.1 初识Spring2.1.1 Spring家族2.1.2 了解Spring发展史 2.2 Spring系统架构2.2.1 系统架构图2.2.2 课程学习路线 2.3 Spring核心概…

Linux实验记录:使用Apache的虚拟主机功能

前言&#xff1a; 本文是一篇关于Linux系统初学者的实验记录。 参考书籍&#xff1a;《Linux就该这么学》 实验环境&#xff1a; VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 正文&#xff1a; 目录 前言&#xff1a; 正文&…

【重温设计模式】构建器及其Java示例

设计模式中的构建器模式介绍 在编程的世界里&#xff0c;设计模式是一种让我们的代码更加优雅、可读、可维护的工具。其中&#xff0c;构建器模式是一种创建型模式&#xff0c;它提供了一种高效且灵活的方式来创建复杂对象。这种模式的主要特点是&#xff0c;它分离了对象的构…

易点易动设备管理平台助力制造企业实现设备的智能化维修和保养管理

在制造业领域&#xff0c;设备的维修和保养是保障生产运行和产品质量的关键环节。然而&#xff0c;传统的维修和保养管理方式往往存在效率低下、难以及时发现问题等问题。为了解决这些挑战&#xff0c;易点易动设备管理平台应运而生。该平台利用物联网和数据分析技术&#xff0…

回归预测 | Matlab实现CPO-GRU【24年新算法】冠豪猪优化门控循环单元多变量回归预测

回归预测 | Matlab实现CPO-GRU【24年新算法】冠豪猪优化门控循环单元多变量回归预测 目录 回归预测 | Matlab实现CPO-GRU【24年新算法】冠豪猪优化门控循环单元多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-GRU【24年新算法】冠豪猪优化…

sectigo ip ssl证书有哪些

Sectigo是移交成立时间较久的CA认证机构&#xff0c;几十年来在全球颁发了各种各样的数字证书&#xff0c;例如&#xff0c;单域名SSL证书、多域名SSL证书、通配符SSL证书等域名SSL证书。Sectigo旗下也有一些不常见的数字证书&#xff0c;例如&#xff0c;代码签名证书、IP证书…

【设计模式】六大原则详解,每个原则提供代码示例

设计模式六大原则 目录 一、单一职责原则——SRP 1、作用2、基本要点3、举例 二、开放封闭原则——OCP 1、作用2、基本要点3、举例 三、里氏替换原则——LSP 1、作用2、基本要点3、举例 四、依赖倒置原则——DLP 1、作用2、基本要点3、举例 五、迪米特法则——LoD 1、作用2、…

C++数据结构——红黑树

一&#xff0c;关于红黑树 红黑树也是一种平衡二叉搜索树&#xff0c;但在每个节点上增加一个存储位表示节点的颜色&#xff0c;颜色右两种&#xff0c;红与黑&#xff0c;因此也称为红黑树。 通过对任意一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树可以…

(2)SpringBoot学习——芋道源码

Spring Boot 的自动配置 1.概述 EmbeddedWebServerFactoryCustomizerAutoConfiguration 类 Configuration // <1.1> ConditionalOnWebApplication // <2.1> EnableConfigurationProperties(ServerProperties.class) // <3.1> public class EmbeddedWebSe…

推荐一个好用的旧版本软件安装包下载地址

最近要下载旧版本的mysql和postman&#xff0c;发现官网和其他博客里边提供的地址&#xff0c;要不都非常难找到相应的下载链接&#xff0c;要不就是提供的从别的地方复制过来的垃圾教程&#xff0c;甚至有的下载还要积分&#xff0c;反正是最后都没下载成功&#xff0c;偶然发…

nodejs基于vue奖学金助学金申请系统08ktb

高校奖助学金系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品&#xff0c;体验高科技时代带给人们的方便&#xff0c;同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓&#xff0c;iOS相比较起来&#xff0c;…

期末成绩群发给家长

每当学期结束&#xff0c;老师们的邮箱和手机便会被成绩报告单填满。那么&#xff0c;如何高效地将成绩群发给家长呢&#xff1f; 一、邮件还是短信&#xff1f; 首先&#xff0c;选择一个合适的通讯方式是关键。邮件正式且便于附件&#xff0c;但短信更快捷。考虑到大多数家长…

windows平台使用tensorRT部署yolov5详细介绍,整个流程思路以及细节。

目录 Windows平台上使用tensorRT部署yolov5 前言&#xff1a; 环境&#xff1a; 1.为什么要部署&#xff1f; 2.那为什么部署可以解决这个问题&#xff1f;&#xff08;基于tensorRT&#xff09; 3.怎么部署&#xff08;只讨论tensorRT&#xff09; 3.0部署的流程 3.1怎…