[架构之路-158]-《软考-系统分析师》-13-系统设计 - 高内聚低耦合详解、图解以及技术手段

news2024/11/23 20:03:33

目录

第1章  什么是高内聚低耦合

1.1 概念

1.2 目的

1.3 什么时候需要进行高内聚低耦合

1.4 什么系统需要关注高内聚、低耦合

第2章 分类

2.1 内聚的分类

2.2 耦合的分类

第3章  增加高内聚降低耦合度的方法

3.1 增加高内聚

3.2 降低耦合度


第1章  什么是高内聚低耦合

1.1 概念

高内聚低耦合,是软件工程中的概念,是判断软件设计好坏的标准,主要用于程序的面向对象的设计,主要看类的内聚性是否高,耦合度是否低。

内聚是从功能角度来度量模块内部的各子模块之间的相似性的程度,一个好的内聚模块应当恰好做一件事,它描述的是模块内的功能联系

耦合是从接口角度来度量模块与外界之间的相互连接、相互依赖、相互影响的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。

1.2 目的

目的是增加程序模块的可重用性、增强程序的移植性,同时也有助于系统的有序性、

通常程序结构中各模块的内聚程度越高,模块间的耦合程度就越低

高内聚具备可靠性,可重用性,可读性等优点,模块设计推荐采用高内聚。

1.3 什么时候需要进行高内聚低耦合

在系统设计的概要设计阶段,对软件进行模块切分时,会使用到该概念。

需要注意的是,当你在做「分解」这个操作的时候,务必要关注每一次的「分解」是否满足一个最重要的条件:不同分支上的子问题,不能相互依赖,需要各自独立

因为一旦包含了依赖关系,子问题和父问题之间就失去了可以被「归并」的意义。

比如,一个「问题Z」被分解成了两个子问题,「子问题A」和「子问题B」。但是,解问题A依赖于问题B的答案,解问题B又依赖于问题A的答案。这不就等于没有分解吗?

架构是指可以预制和重构的软件框架结构。普遍指通过某种特定平台,而达到完成整体软件的功能。架构设计是指对软件、硬件、网络、运营、政策等软件设计中的需求和要素进行决策,主要包括体系结构设计和各个层的模块设计。

架构设计目标有个能够最大化的重用。

首先,要在架构的设计中灵活地使用各种共享的,特别是开源的框架技术因为共享的架构可以方便开发组分解问题,从而对项目中的功能模块分为需要内部解决和使用已有外部服务两类,避免了重复开发实现。

其次,尽量使用成熟的框架。由于服务器端软件系统的开发,涉及的知识、内容、要解决的技术问题很多,在某些方面使用第三方成熟的框架,相当于让别人帮助开发者完成了一些基础性的工作,此时开发者只需要集中精力完成系统业务逻辑的设计和实现。使软件系统实现可扩展性在技术上灵活地使用各种架构模式和代码设计模式,并且在使用代码设计模式的同时,使用其所提倡的面向接口编程,会对软件系统的可扩展性和可移植性的提高有所帮助。

希望能够设计出“高内聚、低耦合”的应用系统。这是架构设计最主要的目标,实现系统的高内聚、低耦合遵从以下原则:

  • 利用分层架构实现系统在纵向上的低藕合;利用开源框架进一步确保纵向分层的具体实现;
  • 按照功能划分子系统来实现横向上的低偶合;利用包结构确保横向上低耦合的具体实现。

1.4 什么系统需要关注高内聚、低耦合

只有一个大型的软件系统,需要对软件系统进行大量的模块切分时,才会需要到高内聚、低耦合设计思想。

一个小型的软件系统,是不需要考虑高内聚、低耦合。

第2章 分类

2.1 内聚的分类

内聚:故名思议,表示内部间聚集、关联的程度,那么高内聚就是指要高度的聚集和关联

内聚标志一个模块内各个元素彼此结合的紧密程度,它是信息隐蔽局部化概念的自然扩展。

内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系。

  • 偶然内聚:一个模块内的各处理元素之间没有任何逻辑上的联系,只是偶然地被凑到一起。这种模块也称为巧合内聚内聚程度最低
  • 逻辑内聚:这种模块把几种相关的功能组合在一起, 每次被调用时,由传送给模块参数来确定该模块应完成哪一种功能 。
  • 时间内聚:把需要同时执行的动作组合在一起形成的模块称为时间内聚模块。纯粹是因为执行时间相同,并没有功能/目标一致上的关系。
  • 先后过程内聚:构件或者操作的组合方式是,允许在调用前面的构件或操作之后,马上调用后面的构件或操作,即使两者之间没有数据进行传递。简单的说就是如果一个模块内的处理元素是相关的,而且必须以特定次序执行则称为过程内聚。例如某要完成登录的功能,前一个功能判断网络状态,后一个执行登录操作,显然是按照特定次序执行的。
  • 信息通信内聚:指模块内所有处理元素都在同一个数据结构上操作或所有处理功能都通过公用数据而发生关联(有时称之为信息内聚)。即指模块内各个组成部分都使用相同的数据结构或产生相同的数据结构
  • 逻辑顺序内聚:一个模块中各个处理元素和同一个功能密切相关,而且这些处理必须顺序执行,通常前一个处理元素的输出时后一个处理元素的输入。例如某要完成获取订单信息的功能,前一个功能获取用户信息,后一个执行计算均价操作,显然该模块内两部分紧密关联。顺序内聚的内聚度比较高,但缺点是不如功能内聚易于维护。
  • 功能内聚:模块内所有元素的各个组成部分全部都为完成同一个功能或目标而存在,共同完成一个单一的功能,模块已不可再分。即模块仅包括为完成某个功能所必须的所有成分,这些成分紧密联系、缺一不可,不多不少,凝聚力强!

2.2 耦合的分类

耦合:是对模块间关联程度的度量。

耦合的强弱取决与模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。

模块间的耦合度是指模块之间的依赖关系,包括:

  • 控制关系
  • 调用关系
  • 数据传递关系。

模块间联系越多,其耦合性越强,同时表明其独立性越差。

降低模块间的耦合度能减少模块间的影响,防止对某一模块修改所引起的“牵一发动全身”的水波效应,保证系统设计顺利进行。

耦合度就是某模块(类)与其它模块(类)之间的关联、感知和依赖的程度,是衡量代码独立性的一个指标。

  • 非直接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过主模块控制调用实现的耦合度最弱,模块独立性最强。
  • 函数调用/发送消息:值数据耦合:调用模块被调用模块之间只传递简单的数据项参数。相当于高级语言中的值传递
  • 函数调用/发送消息:标记/地址耦合:调用模块和被调用模块之间传递数据结构而不是简单数据,同时也称作特征耦合。模块间传递的不是简单变量值,而是像高级语言中的数据名、记录名和文件名等数据的标记,这些名字即为标记,其实传递的是地址
  • 备注:数据耦合相对于控制耦合,是松耦合,因为万事万物,总会有些信息联系的。
  • 函数调用/发送消息:控制耦合:模块之间传递的不是数据信息,而是控制信息,例如标志、开关量等,一个模块控制了另一个模块的功能。
  • 共享资源:外部变量耦合、外部耦合:一组模块都访问同一全局简单变量,而且不通过参数表传递该全局变量的信息,则称之为外部耦合。
  • 共享资源:公共数据耦合:一组模块都访问同一个全局数据结构,则称之为公共耦合。公共数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。如果模块只是向公共数据环境输入数据,或是只从公共数据环境取出数据,这属于比较松散的公共耦合;如果模块既向公共数据环境输入数据又从公共数据环境取出数据,这属于较紧密的公共耦合。
  • 内容耦合:是指如果一个模块与另一个模块的内部属性有关,不经调用直接使用另一个模块的程序代码或内部数据,那么这两个模块之间就存在内容耦合。这种耦合表明一个模块与另一个模块的内部数据或程序代码有关,当一个模块的程序代码被修改或内部数据出错,必然引起另一个模块出错。而对后一模块的出错是很难查出原因的,这样给模块的修改、维护带来极大困难。内容耦合的耦合度最大,为“病态耦合”,在设计时,应避免这种耦合。在高级语言中,实际上已经规避了该类型的耦合,只有在汇编语言中,一个模块、函数才能直接访问另一个函数内部的变量和内存空间!!!

备注0:

共享资源虽然是高耦合,但并非一无是处,当两个模块之间需要高性能数据交换时,共享内存(共享数据)是一个非常高效的手段!!!

备注1:不存在完全孤立的模块

没有与外界完全没有耦合的模块,与外界完全没有耦合的模块是信息孤岛,是没有存在的意义和价值的!!!!

备注2:公共耦合会引起以下问题

1. 无法控制各个模块对公共数据的存取,严重影响了软件模块的可靠性和适应性

2. 使软件的可维护性变差。若一个模块修改了公共数据,则会影响相关模块。

3. 降低了软件的可理解性。不容易清楚知道哪些数据被哪些模块所共享,排错困难。

一般地,仅当模块间共享的数据很多且通过参数传递很不方便时,才使用公共耦合。

备注3:内容耦合

一个模块直接访问另一模块的内容,则称这两个模块为内容耦合。

若在程序中出现下列情况之一,则说明两个模块之间发生了内容耦合:

1. 一个模块直接访问另一个模块的内部数据。

2. 一个模块不通过正常入口而直接转入到另一个模块的内部。

3. 两个模块有一部分代码重叠(该部分代码具有一定的独立功能)。

4. 一个模块有多个入口。

内容耦合可能在汇编语言中出现。大多数高级语言都已设计成不允许出现内容耦合。这种耦合的耦合性最强,模块独立性最弱。

第3章  增加高内聚降低耦合度的方法

3.1 增加高内聚

  • 1、模块只对外暴露最小限度的接口,暂时不需要的接口,不需要暴露,形成最低的依赖关系。
  • 2、只要对外接口不变,模块内部的修改,就不得影响其他模块。
  • 3、删除一个模块,应当只影响有依赖关系的其他模块,而不应该影响其他无关部分。

3.2 降低耦合度

1、少使用类的继承,多用接口隐藏实现的细节。

Java面向对象编程引入接口除了支持多态外, 隐藏实现细节也是其中一个目的。

继承能很好的利用现有内的结构化定义,但也会导致两个类深度耦合。

2、模块的功能化分尽可能的单一

道理也很简单,功能单一的模块供其它模块调用的机会就少。

(其实这是高内聚的一种说法,高内聚低耦合一般同时出现)。

3、遵循一个定义只在一个地方出现。

4、少使用全局变量

5、类属性和方法的声明少用public,多用private关键字。

public的本质就是类的接口,接口越多,对外的依赖性越大。public属性越少,与外界的接口越少。

6、多用设计模式,比如采用MVC的设计模式就可以降低界面与业务逻辑的耦合度。

设计模式本身,就是遵循高内聚、低耦合的原则设计的模式!!!

7、尽量不用“硬编码”的方式写程序,同时也尽量避免直接用SQL语句操作数据库。

摆脱业务代码与数据库的强耦合。

8、最后当然就是避免直接操作或调用其它模块或类的数据(内容耦合);

如果模块间必须存在耦合,原则上尽量使用数据耦合少用控制耦合限制公共耦合的范围避免使用内容耦合

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

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

相关文章

seurat -- 关于DE gene的讨论

实例 # 加载演示数据集 library(Seurat) library(SeuratData) pbmc <- LoadData("pbmc3k", type "pbmc3k.final")# list options for groups to perform differential expression on levels(pbmc)## [1] "Naive CD4 T" "Memory CD4 T…

Orangepi Zero2 全志H616(DHT11温湿度检测)

最近在学习Linux应用和安卓开发过程中&#xff0c;打算把Linux实现的温湿度显示安卓app上&#xff0c;于是在此之前先基于Orangepi Zero2 全志H616下的wiringPi库对DHT11进行开发&#xff0c;本文主要记录开发过程的一些问题和细节&#xff0c;主要简单通过开启线程来接收温湿度…

LeetCode1376. 通知所有员工所需的时间

【LetMeFly】1376.通知所有员工所需的时间 力扣题目链接&#xff1a;https://leetcode.cn/problems/time-needed-to-inform-all-employees/ 公司里有 n 名员工&#xff0c;每个员工的 ID 都是独一无二的&#xff0c;编号从 0 到 n - 1。公司的总负责人通过 headID 进行标识。…

QML动画分组(Grouped Animations)

通常使用的动画比一个属性的动画更加复杂。例如你想同时运行几个动画并把他们连接起来&#xff0c;或者在一个一个的运行&#xff0c;或者在两个动画之间执行一个脚本。动画分组提供了很好的帮助&#xff0c;作为命名建议可以叫做一组动画。有两种方法来分组&#xff1a;平行与…

SNAP + StaMPS 处理Sentinel-1哨兵1 时间序列

SNAP StaMPS 处理Sentinel-1哨兵1 时间序列 Step0: 文件准备及路径设置 0.1 前往GitHub下载snap2stamps: Github snap2stamps 0.2 新建工作路径&#xff0c;用来进行数据处理&#xff0c;并将下载的snap2stamps解压到该文件夹下&#xff0c;并新建两个文件夹&#xff0c;ma…

二叉搜索树的最小绝对差

1题目 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&#xff1a; 输入&#xff1a;root [4,2,6,1,3] 输出&#xff1a;1示例 2&#xff1a; 输入&#xff1a;r…

证券从业资格证-考前复习

备考2023年6月证券从业资格证&#xff0c;每章思维导图及相关概念&#xff0c;用于考前复习 1. 金融市场基础知识 1.1 第一章 金融市场体系 #mermaid-svg-XEPZZTVBmo6nGm2Y {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#merm…

【14.HTML-移动端适配】

移动端适配 1 布局视口和视觉视口1.1 设置移动端布局视口宽度 2 移动端适配方案2.1 rem单位动态html的font-size&#xff1b;2.2 vw单位2.3 rem和vw对比2.4 flex的弹性布局 1 布局视口和视觉视口 1.1 设置移动端布局视口宽度 避免布局视口宽度默认980px带了的缩放问题,并且禁止…

周赛343(模拟、网格图求最短路、贪心)

文章目录 周赛343[6341. 保龄球游戏的获胜者](https://leetcode.cn/problems/determine-the-winner-of-a-bowling-game/)模拟 技巧 [2661. 找出叠涂元素](https://leetcode.cn/problems/first-completely-painted-row-or-column/)模拟 [2662. 前往目标的最小代价](https://lee…

给jar包编写start和stop脚本

文章目录 前言一、编写脚本1.start.sh2.stop.sh3.restart.sh 二、展示总结 前言 springboot项目内置tomcat,一般都是以jar包形式对外发布服务,我们不能每次都去kill pid,抽到脚本里来做这个事会方便许多。 一、编写脚本 1.start.sh #!/bin/bash APP_NAME"springboot2.3…

基于深度学习的水果检测与识别系统(Python界面版,YOLOv5实现)

摘要&#xff1a;本博文介绍了一种基于深度学习的水果检测与识别系统&#xff0c;使用YOLOv5算法对常见水果进行检测和识别&#xff0c;实现对图片、视频和实时视频中的水果进行准确识别。博文详细阐述了算法原理&#xff0c;同时提供Python实现代码、训练数据集&#xff0c;以…

QT 中的多线程之 moveToThread

文章目录 1. 概述2. 方法描述3. 代码&#xff1a;4. 运行结果及说明5. 注意事项6. 结语 1. 概述 ​QThread 类提供了一个与平台无关的管理线程的方法。一个 QThread 对象管理一个线程。 QThread 的执行从 run() 函数的执行开始&#xff0c;在 Qt 自带的 QThread 类中&#xf…

GraalVM编译SpringBoot程序

GraalVM 提供了一个名为 “Native Image” 的工具&#xff0c;它能够将 Java 应用程序预编译成本机可执行文件。这种方法的优点是启动速度快&#xff0c;内存占用少&#xff0c;因为程序运行时不需要 JVM 和类加载。 然而这种方式也存在一些弊端&#xff0c;如预编译的 GraalV…

扩展ACL配置

扩展ACL配置 【实验目的】 掌握扩展ACL的配置。认识扩展ACL的作用。验证配置。 【实验拓扑】 实验拓扑如图1所示。 图1 实验拓扑 设备参数如表所示。 表1 设备参数表 设备 接口 IP地址 子网掩码 默认网关 R1 S0/3/0 192.168.1.1 255.255.255.252 N/A Fa0/0/0 …

操作系统:文件系统基础

文件系统基础 ​ 文件是以硬盘为载体的存储在计算机上的信息集合&#xff0c;文件可以是文档、图片、程序等。在系统运行时&#xff0c;计算机以进程为基本单位进行资源的调度和分配&#xff1b;而在用户的输入和输出中&#xff0c;则以文件为基本单位 文件控制块和索引节点 …

【Python基础练习100题--第二篇:文件篇】

前言 这些题都是在B站的练习题&#xff0c;链接在这 对于刚学python的新手来说十分的适合&#xff0c; 可以加强和巩固我们的基础。 嘿嘿 一起噶油吧&#xff01;&#x1f349; &#x1f349;1.对学生成绩排序 # 这里对字典进行排序&#xff0c;同事使用到了sorted函数 # 这…

stm32F103 WIFIESP8266模块连接阿里云平台

(43条消息) ESP8266 AT MQTT 透传指令接入阿里云物联网平台笔记&#xff1b;_安信可科技的博客-CSDN博客 这里这篇博客提到的固件是错误的 我用的固件是这个&#xff0c;刷固件之后&#xff0c;可以连上阿里云。 ATMQTTCLIENTID0,"ClienId"//clientId第二个参数注…

权限提升:烂土豆 || DLL 劫持.

权限提升&#xff1a;烂土豆 || DLL 劫持. 权限提升简称提权&#xff0c;由于操作系统都是多用户操作系统&#xff0c;用户之间都有权限控制&#xff0c;比如通过 Web 漏洞拿到的是 Web 进程的权限&#xff0c;往往 Web 服务都是以一个权限很低的账号启动的&#xff0c;因此通…