热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

架构与设计模式的六大原则

编程是一个先思考再编码的过程,思考是优于编码技能的,在思考过程中我们会考虑代码的可重用性、可靠性、更容易被他人理解,这时就会使用到设计模式让代码编写工程化,这篇文章整理了设计模式的

编程是一个先思考再编码的过程,思考是优于编码技能的,在思考过程中我们会考虑代码的可重用性、可靠性、更容易被他人理解,这时就会使用到设计模式让代码编写工程化,这篇文章整理了设计模式的六大原则。


1. 单一职责原则

单一职责原则(Single Responsibility Principle)

There should never be more than one reason for a class to change.(有且仅有一个原因可以引起类的变更)

不管让我干啥,我都只干一件事,你让我下楼取快递,顺便将垃圾带下去,对不起,我不干,我只取快递。

优点:


  • 类的复杂性降低,实现什么职责都有清晰明确的定义;

  • 可读性提高,复杂性降低,那当然可读性提高了;

  • 可维护性提高,可读性提高,那当然更容易维护了;

  • 变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助。


2. 接口隔离原则

接口隔离原则(Interface Segregation Principle)

1、Clients should not be forced to depend upon interfaces that they don't use.(客户端不应该依赖它不需要的接口)

2、The dependency of one class to another one should depend on the smallest possible interface.(类间的依赖关系应该建立在最小的接口上)

举个例子,类A 通过 Interface1 依赖类B,方法1,方法2,方法3;类B 通过 Interface1 依赖D,方法1,方法4,方法5,看下未使用接口隔离原则和使用了接口隔离原则发生了什么变化。


3. 依赖倒置原则

依赖倒置原则(Dependence Inversion Principle)

1、High level modules should not depend upon low level modules.Both should depend upon abstractions. (高层模块不应该依赖低层模块,两者都应该依赖其抽象)

2、Abstractions should not depend upon details. (抽象不应该依赖细节)

3、Details should depend upon abstractions. (细节应该依赖抽象)

举个例子,类A 直接依赖 类B,假如要将 类A 改为依赖 类C,则必须通过修改 类A 的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B 和类C 是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

解决方案:将 类A 修改为依赖 接口Interface1,类B 和 类C 各自实现 接口Interface1,类A 通过 接口Interface1 间接与 类B 或者 类C 发生联系,则会大大降低修改 类A 的几率。


4. 里氏替换原则

里氏替换原则(Liskov Substitution Principle)

1、If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T,the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.(如果对每一个类型为 S 的对象o1,都有类型为 T 的对象 o2,使得以 T 定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 S 是类型 T 的子类型)

2、Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.(所有引用基类的地方必须能透明地使用其子类的对象)

举个例子,有一功能 P1,由 类A 完成,现需要将功能 P1 进行扩展,扩展后的功能为 P,其中 P 由原有功能 P1 与新功能 P2 组成,新功能 P 由 类A 的 子类B 来完成,则 子类B 在完成新功能 P2 的同时,有可能会导致原有功能 P1 发生故障。

解决方案:当使用继承时,遵循里氏替换原则。类B 继承 类A 时,除添加新的方法完成新增功能 P2 外,尽量不要重写 父类A 的方法,也尽量不要重载父类A的方法。

继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些契约,但是如果子类对这些方法任意修改,就会对整个继承体系造成破坏,而里氏替换原则就是表达了这一层含义。

继承作为面向对象三大特性之一,在给程序设计带来巨大便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加了对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能会产生故障。

优点:


  • 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;

  • 提高代码的重用性,可扩展性。

  • 提高产品或项目的开放性。


5. 迪米特法则

迪米特法则(Law of Demeter)

1、Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.(每个单元对于其他的单元只能拥有有限的知识:只是与当前单元紧密联系的单元)

2、Each unit should only talk to its friends; don't talk to strangers.(每个单元只能和它的朋友交谈:不能和陌生单元交谈)

3、Only talk to your immediate friends.(只和自己直接的朋友交谈)

举个例子,我们通过 手机 阅读 微信读书 APP 内的 书籍,如何设计类的编写?

手机类 和 书籍类,这两个不能直接发生调用关系,需要 手机类 和 微信读书 APP 类先发生调用关系,然后微信读书 APP 类 再和 书籍 类可以发生调用关系,这样才遵循迪米特法则。


6. 开闭原则

开闭原则(Open Closed Principle)

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.(软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的)

在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。

解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。


小结


  • 单一职责原则告诉我们实现类要职责单一;

  • 接口隔离原则告诉我们在设计接口的时候要精简单一;

  • 依赖倒置原则告诉我们要面向接口编程;

  • 里氏替换原则告诉我们不要破坏继承体系;

  • 迪米特法则告诉我们要降低耦合;

  • 开闭原则是总纲,告诉我们要对扩展开放,对修改关闭;

转载:架构与设计模式的六大原则 



推荐阅读
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 非公版RTX 3080显卡的革新与亮点
    本文深入探讨了图形显卡的进化历程,重点介绍了非公版RTX 3080显卡的技术特点和创新设计。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 解决PHP与MySQL连接时出现500错误的方法
    本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 尽管使用TensorFlow和PyTorch等成熟框架可以显著降低实现递归神经网络(RNN)的门槛,但对于初学者来说,理解其底层原理至关重要。本文将引导您使用NumPy从头构建一个用于自然语言处理(NLP)的RNN模型。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • Win11扩展卷无法使用?解决扩展卷灰色问题的指南
    本文详细介绍了在Windows 11中遇到扩展卷灰色无法使用时的解决方案,帮助用户快速恢复磁盘扩展功能。 ... [详细]
author-avatar
飞松安步当车9_U
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有