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

4 软件工程——总体设计

一、设计过程

1.两个主要阶段

  • 系统设计阶段:确定系统的具体实现方案
  • 结构设计阶段:确定软件结构

2.九个步骤

  • 设想供选择的方案
  • 选取合理的方案
  • 推荐最佳方案
  • 功能分解
  • 设计软件结构
  • 设计数据库
  • 制定测试计划
  • 书写文档
  • 审查和复审

二、设计原理

1.模块化

        模块化是由边界元素限定的相邻程序元素的序列,而且有一个实体标识符代表着它。

        模块化就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体。

2.抽象

        把相似的方面集中和概括起来,暂时忽略它们之间的差异,这就是抽象。 抽象就是抽出职务的本质特性而暂时不考虑它们的细节

3.逐步求精

        为了能集中精力解决主要问题而尽量推迟对问题细节的考虑。

        逐步求精可以看座是一项把一个时期内必须解决的种种问题按优先级排序的技术。

4.信息隐藏和局部化

        把一些关系密切的软件元素物理地放得彼此靠近。在模块中使用局部数据元素是局部化的一个例子,显得局部化有助于实现信息隐藏。

5.模块独立

        开发具有独立功能而且和其他模块之间没以后过多的相互作用的模块,就可以做到模块独立。换句话说,希望这样设计软件结构,使得每个模块完成一个相对独立的特定子功能,并且和其他模块之间的关系很简单。为什么说模块的独立性很重要呢?

  • 有效的模块化的软件比较容易开发出来
  • 独立的模块比较容易测试和维护

(1)耦合

        耦合是对一个软件结构内模块之间互连程度的度量。耦合度越高,模块之间的依赖关系越紧密,系统的灵活性和可维护性越差。理想的设计是尽量减少耦合,使得模块之间相对独立。

        排序(低到高):

                非直接耦合<数据耦合<标记耦合<控制耦合<外部耦合<公共耦合<内部耦合

        尽量使用数据耦合,少用控制耦合和特征耦合,限制公共环境耦合的范围,完全不用内容耦合。

1.1 非直接耦合
  • 定义:模块之间存在间接依赖,即一个模块通过其他模块或中介进行交互,而不是直接依赖于另一个模块的内部实现。
  • 特点:通过引入中介或抽象层减少模块间的直接依赖,提高模块的独立性。
  • 示例:模块A通过接口或服务与模块B进行交互,而不是直接调用模块B的内部方法。
1.2 数据耦合(低耦合)
  • 定义:两模块彼此通过参数交换数据信息,模块之间没有控制依赖。
  • 特点:数据耦合度最低,模块间通过数据交换而不影响彼此的实现,能有效减少模块间的依赖关系。
  • 示例:模块A将一个数据对象传递给模块B,模块B仅使用数据,不控制模块A的行为。
1.3 控制耦合(中等耦合)
  • 定义:传递的信息中带有控制信息,控制信息用来控制模块内部的行为。
  • 特点:模块之间存在控制依赖,即模块通过参数来控制其他模块的行为,耦合度中等。
  • 示例:模块A传递一个控制标志(如布尔值)给模块B,来决定模块B执行不同的操作。
1.4 公共环境耦合
  • 定义:两个或多个模块共享相同的全局数据(通常是全局变量、常量、配置文件等)。
  • 特点:公共环境耦合度较高,因为多个模块共享同一全局数据,可能会导致数据污染或意外的依赖关系。
  • 示例:模块A和模块B共享一个全局变量 counter,任何一个模块对它的修改都会影响到另一个模块。
1.5 内容耦合(最高耦合)
  • 定义:一个模块直接访问另一个模块的内部数据或实现细节,甚至直接修改另一个模块的代码。
  • 特点:内容耦合是耦合度最高的类型,模块之间高度依赖,修改一个模块的内部实现可能会影响到多个模块。
  • 示例:模块A直接修改模块B的内部数据或访问模块B的私有字段和方法。

(2)内聚

        内聚是衡量一个模块内部各个部分之间紧密程度的度量。内聚度越高,模块内部的元素协同工作,功能越专一,系统的可维护性和可理解性越强。

         排序(低到高):

        偶然内聚<逻辑内聚<时间内聚<过程内聚<通信内聚<顺序内聚<功能内聚

        尽量追求高内聚,确保模块的功能明确且专一。

2.1 功能内聚(Functional Cohesion)
  • 定义:功能内聚是指模块内部的所有元素都紧密地协作以完成同一个功能或任务。
  • 特点:功能内聚性最强,模块的每个部分都朝着一个明确的目标协作,符合单一职责原则。
  • 示例:一个处理用户注册的模块,所有代码都围绕着处理用户注册的具体任务展开。
2.2 顺序内聚(Sequential Cohesion)
  • 定义:顺序内聚是指模块内部的各个部分按顺序执行,每个部分的输出是下一个部分的输入。
  • 特点:操作有序,前一个操作的结果是下一个操作的输入。
  • 示例:数据处理模块,先进行数据格式化,再进行数据分析,最后输出结果。
2.3 通信内聚(Communicational Cohesion)
  • 定义:通信内聚是指模块内部的各个部分共同操作同一组数据。
  • 特点:虽然模块内部的操作功能不同,但它们都操作相同的数据。
  • 示例:一个模块内的数据处理操作,操作相同的数据集(例如,同一个用户对象的多个属性)。
2.4 过程内聚(Procedural Cohesion)
  • 定义:过程内聚是指模块内的各个部分执行的任务虽然不同,但执行顺序上的相关性较强,必须按特定的顺序来执行这些任务。
  • 特点:模块内的操作是为了完成一个大任务的几个步骤。
  • 示例:一个模块负责验证输入数据、读取数据库、格式化输出等任务,这些任务在流程上有先后顺序。
2.5 时间内聚(Temporal Cohesion)
  • 定义:时间内聚是指模块内的各个部分需要在同一时间点执行,但这些操作的功能没有直接关系。
  • 特点:模块内的各部分功能不同,但它们在时间上被安排为同时执行。
  • 示例:一个系统初始化模块,在系统启动时执行多个初始化任务,如加载配置文件、初始化连接池等。
2.6 逻辑内聚(Logical Cohesion)
  • 定义:逻辑内聚是指模块内的各个部分负责处理同一类任务,但每个任务执行的功能不同。
  • 特点:模块内的操作虽然属于同一类别,但功能不同,通常通过一些条件判断来决定具体执行哪一部分任务。
  • 示例:一个模块根据不同的用户请求类型(如:打印、计算、存储)执行不同的功能。
2.7 偶然内聚(Coincidental Cohesion)
  • 定义:偶然内聚是指模块内的各个部分没有共同目标,它们的功能完全不相关,只是偶然地被放在同一个模块中。
  • 特点:内聚性最差,模块内的各个部分之间没有任何联系,模块功能不明确。
  • 示例:一个模块同时处理输入、输出、日志记录和网络通信等任务,它们之间没有任何相关性。

三、启发规则

  1. 改进软件结构提高模块独立性
  2. 模块规模应该适中
  3. 深度、宽度、扇入和扇出都应适当
  4. 模块的作用域应该在控制域之内
  5. 力争降低模块接口的复杂程度
  6. 设计单入口单出口的模块
  7. 模块功能应该可以预测 

四、面向数据流的设计方法

1.变换流

        有明显的输入输出。

        根据基本系统模型,信息通常以“外部世界”的形式进入软件系统,经过处理以后再以“外部世界”的形式离开系统。

2.事务流

        数据沿输入通路到达一个处理,这个处理根据输入数据的类型在若干动作系列中选出一个来执行。这类数据流应该划为一类特殊的数据流,称为事务流。

        有事务中心:

  • 接收输入数据(输入数据又称为事务)
  • 分析每个事务以确定它的类型
  • 根据事务类型选取一条活动通路

相关文章:

4 软件工程——总体设计

一、设计过程 1.两个主要阶段 系统设计阶段&#xff1a;确定系统的具体实现方案结构设计阶段&#xff1a;确定软件结构 2.九个步骤 设想供选择的方案选取合理的方案推荐最佳方案功能分解设计软件结构设计数据库制定测试计划书写文档审查和复审 二、设计原理 1.模块化 模块…...

Elasticsearch:确保业务规则与语义搜索无缝协作

作者&#xff1a;来自 Elastic Kathleen DeRusso 利用查询规则与语义搜索和重新排序相结合的强大功能。 更多阅读&#xff1a; Elasticsearch 8.10 中引入查询规则 - query rules Elasticsearch 查询规则现已正式发布 - query rules 你是否知道查询规则&#xff08;query ru…...

【大语言模型】ACL2024论文-33 Johnny 如何说服大型语言模型越狱:通过人性化 LLMs 重新思考挑战 AI 安全性的说服技巧

【大语言模型】ACL2024论文-33 Johnny 如何说服大型语言模型越狱&#xff1a;通过人性化 LLMs 重新思考挑战 AI 安全性的说服技巧 目录 文章目录 【大语言模型】ACL2024论文-33 Johnny 如何说服大型语言模型越狱&#xff1a;通过人性化 LLMs 重新思考挑战 AI 安全性的说服技巧目…...

【LuaFramework】LuaFramework_UGUI_V2框架学习

GitHub - jarjin/LuaFramework_UGUI_V2: 基于tolua的热更新框架V2 旧版本是Unity 5.0&#xff0c;这个是新版本支持更高版本的 导入工程后先清除wrap 然后重新生成wrap&#xff0c;你会发现有个报空null&#xff0c;框架的问题总结下所有的框架wrap相关报错问题和修复方法&…...

使用 AOP 在 Spring Boot 中实现跟踪和日志记录

在现代应用程序中&#xff0c;尤其是使用微服务构建的应用程序&#xff0c;跟踪和日志记录在跟踪流经各种服务的请求方面起着至关重要的作用。跟踪可帮助开发人员诊断问题、监控性能并了解用户在多个系统中的旅程。 在此博客中&#xff0c;我们将介绍如何使用traceId从前端生成…...

如何永久解决Apache Struts文件上传漏洞

Apache Struts又双叒叕爆文件上传漏洞了。 自Apache Struts框架发布以来&#xff0c;就存在多个版本的漏洞&#xff0c;其中一些漏洞涉及到文件上传功能。这些漏洞可能允许攻击者通过构造特定的请求来绕过安全限制&#xff0c;从而上传恶意文件。虽然每次官方都发布补丁进行修…...

FPGA远程升级 -- FLASH控制

简介 前文讲到如何实现XILINX芯片程序跳转&#xff0c;但升级程序是事先通过VIVADO工具将两个程序合成一个BIN文件实现升级的&#xff0c;并不能在线更新升级。要实现远程升级的能力需要对FPGA的FLASH进行在线写入升级程序。 FLASH介绍 本次设计FLASH选用的是S25FL128芯片&…...

企业内训|高智能数据构建、Agent研发及AI测评技术内训-吉林省某汽车厂商

吉林省某汽车厂商为提升员工在AI大模型技术方面的知识和实践能力&#xff0c;举办本次为期8天的综合培训课程。本课程分为两大部分&#xff1a;面向全体团队成员的AI大模型技术结构与行业应用&#xff0c;以及针对技术团队的高智能数据构建与Agent研发。课程内容涵盖非结构化数…...

ARM异常处理 M33

1. ARMv8-M异常类型及其详细解释 ARMv8-M Exception分为两类&#xff1a;预定义系统异常(015)和外部中断(1616N)。 各种异常的状态可以通过Status bit查看&#xff0c;获取更信息的异常原因&#xff1a; CFSR是由UFSR、BFSR和MMFSR组成&#xff1a; 下面列举HFSR、MMFSR、…...

(补)算法刷题Day24: BM61 矩阵最长递增路径

题目链接 思路 方法一&#xff1a;dfs暴力回溯 使用原始used数组4个方向遍历框架 &#xff0c; 全局添加一个最大值判断最大的路径长度。 方法二&#xff1a;加上dp数组记忆的优雅回溯 抛弃掉used数组&#xff0c;使用dp数组来记忆遍历过的节点的最长递增路径长度。每遍历到已…...

探索 Bokeh:轻松创建交互式数据可视化的强大工具

探索 Bokeh&#xff1a;轻松创建交互式数据可视化的强大工具 在数据科学和数据分析领域&#xff0c;交互式数据可视化是一项不可或缺的技能。Bokeh 是一个强大的 Python 库&#xff0c;它可以帮助我们快速构建高质量的交互式图表和仪表盘&#xff0c;同时兼具高性能和灵活性。…...

【Rust自学】6.1. 定义枚举

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 6.1.1. 什么是枚举 枚举允许我们列举所有可能的值来定义一个类型。这与其他编程语言中的枚举类似&#xff0c;但 Rust 的枚举更加灵活和强…...

【Java基础面试题035】什么是Java泛型的上下界限定符?

回答重点 Java泛型的上下界限定符用于对泛型类型参数进行范围限制&#xff0c;主要有上界限定符和下届限定符。 1&#xff09;上界限定符 (? extends T)&#xff1a; 定义&#xff1a;通配符?的类型必须是T或者T的子类&#xff0c;保证集合元素一定是T或者T的子类作用&…...

0基础学前端系列 -- 深入理解 HTML 布局

在现代网页设计中&#xff0c;布局是至关重要的一环。良好的布局不仅能提升用户体验&#xff0c;还能使内容更具可读性和美观性。HTML&#xff08;超文本标记语言&#xff09;结合 CSS&#xff08;层叠样式表&#xff09;为我们提供了多种布局方式。本文将详细介绍流式布局、Fl…...

【python高级】342-TCP服务器开发流程

CS模式&#xff1a;客户端-服务端模式 TCP客户端开发流程介绍&#xff08;五步&#xff09;&#xff08;C端&#xff09; 1.创建客户端套接字对象 2.和服务端套接字建立连接 3.发送数据 4.接收数据 5.关闭客户端套接字 TCP服务端开发流程&#xff08;七步&#xff09;&#xf…...

《计算机组成及汇编语言原理》阅读笔记:p48-p81

《计算机组成及汇编语言原理》学习第 4 天&#xff0c;p48-p81 总结&#xff0c;总计 34 页。 一、技术总结 1.CISC vs RISC p49&#xff0c; complex instruction set computing For example, a complex instruction set computing (CISC) chip may be able to move a lar…...

AI在传统周公解梦中的技术实践与应用

本文深入探讨了人工智能在传统周公解梦领域的技术实践与应用。首先介绍了传统周公解梦的背景与局限性&#xff0c;随后详细阐述了 AI 技术如何应用于梦境数据的采集、整理与分析&#xff0c;包括自然语言处理技术对梦境描述的理解&#xff0c;机器学习算法构建解梦模型以及深度…...

GIS数据处理/程序/指导,街景百度热力图POI路网建筑物AOI等

简介其他数据处理/程序/指导&#xff01;&#xff01;&#xff01;&#xff08;1&#xff09;街景数据获取&#xff08;2&#xff09;街景语义分割后像素提取&#xff0c;指标计算代码&#xff08;绿视率&#xff0c;天空开阔度、视觉熵/景观多样性等&#xff09;&#xff08;3…...

ssr实现方案

目录 序言 一、流程 二、前端要做的事情 三、节点介绍 四、总结 序言 本文不是详细的实现过程&#xff0c;是让你最快最直接的理解ssr的真正实现方法&#xff0c;有前端经验的同学&#xff0c;能够很好的理解过程&#xff0c;细节根据具体项目实现 一、前端要做的事情 1.…...

手动修改nginx-rtmp模块,让nginx-rtmp-module支持LLHLS

文章目录 1. 背景2. 开发环境搭建2.1 ffmpeg在ubuntu上安装2.2 nginx-rtmp-module在ubuntu上安装2.3 安装vscode环境2. 修改nginx-rtmp-module2.1 主要更新内容2.2 新增配置项2.3 代码更新3. LLHLS验证方法3.1 配置验证3.2 功能验证4. 注意事项5. 已知问题6. 后续计划1. 背景 …...

gitee别人仓库再上传自己仓库

一、新建一个自己的Git仓库 如果没有注册账号的朋友&#xff0c;可以先去注册一个Gitee的账号&#xff0c;用于管理自己的代码特别好用&#xff01;&#xff01;&#xff01; 接下来就是在gitee上新建一个自己的仓库&#xff0c;如下图所示 二、右建 Git Bush Here删除.git文件…...

create-react-app 创建react项目报错 ERESOLVE unable to resolve dependency tree

会报下面这样一个错误&#xff0c;这个错误以前是没有的&#xff0c;最近才出现这个错误。这个非常的蛋疼&#xff0c;意思是testing-library这个库的版本需要react18&#xff0c;但现在安装的是react19。 create-react-app的github是有这个issue的&#xff0c;但官方好像没给…...

从git上下载的项目不完整,关于git lfs

文章目录 问题一、git lfs是什么&#xff1f;二、如何获取git lfs中的文件1.安装 Git LFS2.下载文件 问题 在git上下载的项目无法执行,打开相关文件后发现如下内容: git lfs pull version https://git-lfs.github.com/spec/v1 oid sha256:00920b6723bb39321eea748fd96279f8a…...

sqlite3,一个轻量级的 C++ 数据库库!

宝子们&#xff0c;今天咱来唠唠 sqlite3 这个超棒的轻量级 C 数据库库。它就像是一个小巧但功能齐全的“数据仓库”&#xff0c;能帮咱们轻松地存储、查询和管理数据&#xff0c;无论是开发小型的桌面应用&#xff0c;还是做一些简单的数据处理程序&#xff0c;它都能派上大用…...

Pytorch | 从零构建ParNet/Non-Deep Networks对CIFAR10进行分类

Pytorch | 从零构建ParNet/Non-Deep Networks对CIFAR10进行分类 CIFAR10数据集ParNet架构特点优势应用 ParNet结构代码详解结构代码代码详解SSEParNetBlock 类DownsamplingBlock 类FusionBlock 类ParNet 类 训练过程和测试结果代码汇总parnet.pytrain.pytest.py 前面文章我们构…...

验证 Dijkstra 算法程序输出的奥秘

一、引言 Dijkstra 算法作为解决图中单源最短路径问题的经典算法,在网络路由、交通规划、资源分配等众多领域有着广泛应用。其通过不断选择距离源节点最近的未访问节点,逐步更新邻居节点的最短路径信息,以求得从源节点到其他所有节点的最短路径。在实际应用中,确保 Dijkst…...

二叉树的最小深度

最小深度思路解析: 与求最大深度相比,求最小深度就要简单很多,从上向下访问,只要访问到一个叶节点,证明已经到达了与根节点距离最近的叶节点处,此叶节点的深度即为最小深度.借助队列,如果当前节点为叶节点,则返回该节点的深度为最终结果;如果当前节点不满足上述判断且不为空节…...

C#+OpenCv深度学习开发(常用模型汇总)

在使用 OpenCvSharp 结合深度学习进行机器视觉开发时&#xff0c;有许多现成的模型可以使用。以下是一些常用的深度学习模型&#xff0c;适用于不同的机器视觉任务&#xff0c;包括物体检测、图像分类和分割等。 使用示例 在 OpenCvSharp 中加载和使用这些模型的基本示例&…...

什么样的LabVIEW控制算自动控制?

自动控制是指系统通过预先设计的算法和逻辑&#xff0c;在无人工干预的情况下对被控对象的状态进行实时监测、决策和调整&#xff0c;达到预期目标的过程。LabVIEW作为一种图形化编程工具&#xff0c;非常适合开发自动控制系统。那么&#xff0c;什么样的LabVIEW控制算作“自动…...

Linux系统编程——理解系统内核中的信号捕获

目录 一、sigaction() 使用 信号捕捉技巧 二、可重入函数 三、volatile关键字 四、SIGCHLD信号 在信号这一篇中我们已经学习到了一种信号捕捉的调用接口&#xff1a;signal(),为了深入理解操作系统内核中的信号捕获机制&#xff0c;我们今天再来看一个接口&#xff1a;si…...