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

面向对象设计原则(一)

面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计模式中,它们是从许多设计方案中总结出的指导性原则。

单一职责原则

单一原则(Single Responsibility Principle,SRP)是最简单的设计原则,它用来控制类的颗粒度大小。
RoleDataOperation类承载了数据库连接、数据库数据操作、存档数据业务操作的功能职责,不符合单一职责。
下面来改进一下。

开闭原则

开闭原则(Open-Closed Principle ,OCP)是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则。
在开闭原则的定义中,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类
开闭原则就是指软件实体尽量在不修改源码的情况下进行扩展。
开闭原则是评价基于某个设计模式设计的系统是否具备灵活性和可扩展性的重要依据。
下面来模拟一个刷怪塔
createMonster用如下实现代码
此时如果新增一种类型的怪物,那么必然会修改createMonster的业务逻辑,不符合开闭原则,下面来来修改一下。

里氏替换原则

如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1代换o2时,程序P的行为没有变化,那么类型S是类型T的子类型。
这个定义比较拗口且难以理解,因此我们一般使用它的另一个通俗版定义:所有引用基类(父类)的地方必须能透明地使用其子类的对象。
里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象
在程
序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。
兼容LSP设计原则的execute方法
/ 创建Audio产品对象 Product* audio = new Audio(); audio->setFilePath("audio.mp3"); / 创建Video产品对象 Product* video = new Video(); video->setFilePath("video.mp4"); / 呼叫下载方法下载不同的产品 download(audio); download(video);
不兼容LSP设计原则
/ 创建Chocolate产品对象 Product* chocolate = new Chocolate(); chocolate->setFilePath("Chocolate can not be downloaded."); / 呼叫下载方法下载巧克力产品 download(chocolate);
TIP:现在的问题是谁应该对违反LSP负责?是download() 函数的创建者吗?是产品类的创造者吗?还是巧克力类的创造者?
TIP:常见的LSP违规
子类中的退化方法:如果基类有一个方法,但基类的子类不需要该方法,那么如果子类的作者再次
退化该方法,这将是可替代的违规。
从子类抛出异常LSP违规的另一种形式是向子类添加异常,而基类不希望这样。因为那时基类不能被子类替代。

依赖倒置原则

如果说开闭原则是面向对象设计的目标的话,那么依赖倒置原则(Dependence Inversion Principle,DIP)就是面向对象设计的主要实现机制之一,它是系统抽象化的具体实现。
依赖倒置原则定义如下:
高层模块不应该从低层模块导入任何东西,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应当依赖于抽象。
即:针对接口编程,而不是针对实现编程。
依赖倒置原则要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,即使用接口和抽象类进行变量类型声明、参数类型声明、方法返回类型声明,以及数据类型的转换等,而不要用具体类来做这些事情。为了确保该原则的应用,一个具体类应当只实现接口或抽象类中声明过的方法,而不要给出多余的方法,否则将无法调用到在子类中增加的新方法。
在实现依赖倒置原则时,我们需要针对抽象层编程,而将具体类的对象通过依赖注入(DependencyInjection, DI)的方式注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用的注入方式有三种,分别是:构造注入,设值注入(Setter注入)和接口注入
  • 构造注入是指通过构造函数来传入具体类的对象;
  • 设值注入是指通过Setter方法来传入具体类的对象;
  • 接口注入是指通过在接口中声明的业务方法来传入具体类的对象。
这些方法在定义时使用的是抽象类型,在运行时再传入具体类型的对象,由子类对象来覆盖父类对象。
上面示例中DataBiz是典型的针对具体实现进行编程,因此在数据格式变更的时候就需要反复的修改代码。
下面进行重构。
基于依赖倒置原则,新增一个抽象的转换器DataConvertDataBiz针对DataConvert进行编程,然后根据里氏替换原则,程序运行时对父类进行替换,根据开闭原则,将运行对象指定设置到配置文件中。
在上述重构过程中,我们使用了开闭原则、里氏代换原则和依赖倒转原则,在大多数情况下,这三个设计原则会同时出现,开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段,它们相辅相成,相互补充,目标一致,只是分析问题时所站角度不同而已。

接口隔离原则

客户端不应该依赖哪些它不需要的接口。

根据接口隔离原则,当一个接口太大时,我们需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。每一个接口应该承担一种相对独立的角色,不干不该干的事,该干的事都要干。
接口两种不同的含义:
  • 一种是指一个类型所具有的方法特征的集合,仅仅是一种逻辑上的抽象。在ISP可以理解成一种角 色,一个接口只能代表一种角色,此时也可以称之为角色隔离原则
  • 一种是指某种语言具体的接口定义,有严格的定义和结构(如Java中的interface)。在ISP中表 达的意思是指接口仅仅提供客户端需要的行为,客户端不需要的行为则隐藏起来,应当为客户端提 供尽可能小的单独的接口,而不要提供大的总接口。

根据接口隔离原则重构

在使用接口隔离原则时,我们需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。一般而言,接口中仅包含为某一类用户定制的方法即可,不应该强迫客户依赖于那些它们不用的方法。
组合复用原则
组合复用原则
http://www.rkmt.cn/news/1397468.html

相关文章:

  • 5. 【穷举-作业-编程题-3】求阿姆斯特朗数
  • OPC 中国是做什么的?一文读懂 OPC 与 OPD 体系
  • 面试官:说一下 Agent 的常见范式
  • 精通开关电源设计 day1
  • 【限时开源】Claude长文档推理增强工具包(v1.3):自动段落锚定+逻辑图谱构建+矛盾点高亮——仅剩最后87个内测名额
  • 告别多平台折腾!一个 Key 调用国内主流大模型,DMXAPI 开发者实测体验
  • 被骂上热搜!粉木耳标签涉嫌低俗擦边。盒马火速致歉并下架
  • 2026西南方管供应商推荐及选购指南:镀锌方管生产厂家/附近方管批发/附近钢材批发市场/附近钢材采购批发/哪里有方管批发/选择指南 - 优质品牌商家
  • 8051单片机SFR外部访问机制与工程实践
  • 2026年Q2山东家用梯厂家专业度实测对比评测:山东三层电梯、山东二层电梯、山东别墅电梯、山东四层电梯、山东复式楼电梯选择指南 - 优质品牌商家
  • FDE:一个人 + AI,能不能跑通全栈?
  • PatchTST时间序列预测终极指南:从零开始构建精准预测模型
  • 保姆级教程:手把手教你下载并解析行人属性数据集PA100K(附百度云链接)
  • 别怕数学!用Python和NumPy图解机器学习里的线性代数(附代码)
  • MySQL 聚合函数
  • 《jQuery UI 使用指南》
  • 别再手动标点了!OpenCV相机标定后,用undistort()一键搞定图像去畸变(附Python代码)
  • pandas sort_values 排序原理与生产级实战指南
  • 【从零搭建本地电商智能客服 Agent:Dify+Ollama+Qwen3.5 部署全流程】
  • CRNN实战解析:从图像到文本的端到端识别之旅
  • 建筑动画压缩优化:MPEG框架结合DCT与LLE算法实践
  • 2026雨水收集系统厂家推荐榜:消防不锈钢水箱/焊接不锈钢水箱/生活不锈钢水箱/组合式不锈钢水箱/调蓄型雨水收集系统/选择指南 - 优质品牌商家
  • 11- Claude Code 最强插件库详解:从安装到全插件用途全吃透
  • 有哪些一键生成论文工具是真的契合专业内容,而不是模板套话?
  • 人机融合,瓦伦丁的心态越来越好了
  • “智”的起源:现代AI所缺乏的“是非之心”该如何弥补?
  • 简单三步让Zotero中文文献管理效率提升10倍:Jasminum插件完全指南
  • C# 自动化设备运动控制上位机模拟系统
  • 文献综述速成术,从选题到定稿仅需72小时:基于IEEE/ACM双盲评审标准的ChatGPT提示工程实战
  • 模型驱动的汽车稳定性控制系统关键技术【附程序】