软件工程第六周

软件体系结构概述

体系结构:一种思想,而框架就是思想的实现,设计模式就是根据某一特殊问题实现的框架。

  1. 体系结构:体系结构是软件系统的高级结构。它定义了系统的主要组成部分,以及这些部分之间的关系和交互方式。

  2. 框架框架是一个半完整的应用。它实现了一种或多种体系结构,并为特定类型的应用程序提供了一个重用的结构和方法。开发者使用框架作为基础,添加特定功能来创建完整的应用。

  3. 设计模式设计模式是在特定情境下反复出现的问题的通用解决方案。它不是可以直接转化为代码的模板,而是一个关于如何解决问题的描述或模板。

有一个设计模式叫观察者模式,可以根据不同的用户给出不同的视图。


观察者模式

观察者模式是一种行为型设计模式,它定义了对象之间的一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并被自动更新。

关键组成部分

  • 主题(Subject):持有某个重要状态,并允许观察者对象注册和取消注册。

  • 观察者(Observer):一旦主题的状态发生变化,所有注册的观察者都会收到通知。

应用场景

在前端开发中,观察者模式经常被用于实现事件监听和响应。例如,当用户点击按钮或填写表单时,观察者(如事件处理程序)会被通知并执行相应的操作。但是,观察者模式不仅仅是关于“通知变化”;它还可以根据不同的观察者提供不同的信息或视图。这意味着:

  1. 可定制的通知:当主题的状态发生变化时,不同的观察者可能对不同的信息感兴趣。例如,一些观察者可能只关心主题的某个特定部分的变化,而其他观察者可能需要更广泛的更新。

  2. 响应差异:不同的观察者可能会以不同的方式响应相同的状态变化。这种多样性可以通过为每个观察者定义不同的接口或回调函数来实现。

  3. 提供差异化的视图或接口:在某些实现中,主题可以为不同的观察者提供不同的“视图”或接口。例如,一个数据模型(作为主题)可以为管理员观察者提供一个视图,而为普通用户观察者提供另一个视图。这样,基于观察者的角色或需求,他们可以看到数据的不同表示或不同的数据子集。

这种差异化的方法使得观察者模式更加灵活和强大,可以满足各种各样的应用场景和需求。


软件体系结构分类 

构件连接的方式比如过程调用或者中断。

一个系统可能有多个体系结构。

管道和过滤器结构

编译程序、视频播放器就是管道和过滤器结构!信息隐藏!过滤器是一个黑匣子,要很精准的很专注的完成一件事情!

层次体系结构 

在软件工程和系统设计中,层次体系结构是一种逻辑分区,它将系统的不同部分分成相互堆叠的层。每一层都为上面的层提供服务,并从下面的层中获得服务。层次体系结构有一个约束:每一层都只依赖于下一层,不依赖于其他层。

这种方法的主要好处是:

  • 解耦:每一层只关心其下面的层,这有助于隔离变化和减少依赖。
  • 复用性:较低的层可以被多个上层复用。
  • 可维护性:清晰的界限和定义有助于开发和维护。

常见的层次体系结构如OSI网络互连模型。

OSI网络互连模型

OSI(开放系统互连)模型是一个网络体系结构模型,由国际标准化组织(ISO)定义。它将网络协议分成七个不同的层,从物理传输到应用之间的交互。

从下到上,这七层是:

  1. 物理层(Physical Layer):涉及到物理连接、电压、时钟频率等。例如,电缆、交换机、集线器。

  2. 数据链路层(Data Link Layer):确保在物理网络上有一个可靠的链接。这一层经常被分为两个子层:逻辑链路控制(LLC)和介质访问控制(MAC)。

  3. 网络层(Network Layer):处理数据包的发送和路由,例如IP协议。

  4. 传输层(Transport Layer):提供端到端的通信服务,例如TCP和UDP。

  5. 会话层(Session Layer):负责建立、管理和终止会话。

  6. 表示层(Presentation Layer):处理数据格式、加密和解密等功能。

  7. 应用层(Application Layer):为应用程序提供网络服务,例如HTTP、FTP和SMTP。

在OSI模型中,每一层都只依赖于下一层来提供其所需的服务。

C/S与B/S架构

服务器掌管资源。其实可以看作两层客户机/服务器体系结构,也可以看为胖客户机,我们的目标就是让C端尽可能瘦。这样就诞生了三层C/S体系结构,增加了数据库!

MVC架构

由于增加了VIEW,所以mvc更加适用于用户交互。对于mvc模式的讲解,请见文章Springboot知识点必知必会(一)_Joy T的博客-CSDN博客


系统设计原理之模块化

边界元素:{}、begin end等。

最小成本区:7±2原则,介绍请见软件工程第四周-CSDN博客

信息隐藏不是隐藏全部信息,而是有针对的暴露信息!要求高聚合!内部实现再复杂,都可以使用接口暴露出来!

内部资源分配策略、控制接口controlled interface都需要保密!


模块独立——耦合与内聚

耦合

尽量少出现内容耦合、公共耦合与控制耦合呦!

数据耦合

main与sum函数之间交换参数!很多情况下都是数据耦合。但是一定是局部变量的传递!如果传递的是全局变量,则表示公共耦合,其耦合性会大大增加,不好!

特征耦合

这里,住户情况就是整个的数据结构,是一点也不细化啊。这样的话,计算水费和电费都用的是住户情况。一旦住户情况出现问题,这就不知道会不会影响水费或者电费的计算,这就是特征耦合,耦合性较强,不太好。最好是你需要什么数据,就传递什么数据,修改如下:

这就从特征耦合改进到数据耦合了耶!

控制耦合

怎么去理解控制耦合定义中的信号呢?本质上就是分支,主要表示形式如下:

若采用这种控制形式,一旦计算平均分的方法从求平均值变成分别去掉一个最大值和最小值再求平均值,那么计算最高分耶很有可能受到影响。联系第一周软件工程的内容:软件修改是有副作用的!所以我们应该把控制信号变成调用函数的调用判断对象!

公共耦合

公共耦合是指多个模块共享相同的数据,可能导致的问题是数据的不完整性和不一致性。

为了解决这些问题,我们可以采用一些机制和策略来减少或管理公共耦合。比如下图中将读写公共数据的两个模块分为一个模块读,另一个模块写: 

以下是减少公共耦合的一些建议和考虑:

1. 封装

        封装意味着将数据隐藏在模块或对象内部,并只通过定义好的接口访问它。这样,可以确保数据的完整性和一致性,并防止外部模块直接修改数据。

2. 使用服务层或API

        为数据访问提供统一的服务层或API,确保所有的读写操作都经过这一层。这不仅可以保持数据的一致性,还可以为数据访问提供安全和验证机制。

想象你在一个大型酒店办理入住。你不会直接去找清洁员或者房间服务员来拿钥匙,而是去前台。前台是你和酒店的所有服务之间的中介。同样,当软件需要数据时,它不直接去数据库拿,而是通过一个“前台”——服务层或API。这确保了所有的数据请求都统一和有序。

以图书管理系统为例,我们将服务层和API展示在其他文章中,请见

3. 数据访问对象(DAO)

        在设计模式中,DAO是一种低级的数据访问逻辑或操作从高级的业务服务中分离出来的模式。这样可以避免多个模块直接与数据库进行交互,从而减少公共耦合。

在软件设计中,DAO(Data Access Object)层是负责与数据源(例如数据库)进行交互的部分。对于像JDBC或MyBatis这样的技术,DAO层就是定义SQL查询,插入,更新和删除操作的地方。

拿图书管理系统举例,我们可以细化如下:

  1. 实体层(Entity Layer):这里定义了“图书”这一实体的属性和行为。一个图书实体可能有诸如title(标题)、author(作者)、ISBN(国际标准书号)等属性。

  2. DAO层(Data Access Layer)

    • 这是我们定义如何从数据库中获取图书,如何插入新的图书,如何更新图书信息,或如何删除图书的地方。
    • 如果你使用JDBC,你的DAO层可能会包含原始的SQL语句来实现上述操作。

    • 如果你使用MyBatis,你可能会在XML映射文件或注解中定义SQL语句,而DAO层(通常称为Mapper接口)将包含与这些SQL语句对应的Java方法。

  3. 服务层(Service Layer):这是应用程序的核心业务逻辑所在。例如,如果要借出一本书,服务层可能需要首先检查这本书是否已经被其他人借走。这个层级会调用DAO层来获取数据库中的相关数据。

  4. 表示层/控制器层(Presentation/Controller Layer):用户与此层互动。例如,这可以是一个web页面,用户在这里输入书名来查找书籍,或者输入书籍的详细信息来添加新书。

在这个架构中,DAO层是充当桥梁的角色,连接业务逻辑(在服务层)和实际的数据(在数据库中)。其目标是封装与数据访问相关的所有代码,使其他部分的应用程序不需要关心数据访问的具体细节。

4. 事件驱动架构

        使用事件来触发或通知数据更改,而不是直接进行数据操作。这样可以避免直接的数据耦合,并允许模块独立地响应事件。

想象你在一个餐厅里,当你的食物准备好时,服务员会叫你。你不需要每隔几分钟去厨房检查食物是否准备好。这是因为餐厅采用了“事件驱动”的模式——当某个事件(食物准备好)发生时,会有一个相应的动作(叫你)。在软件中,系统也可以这样设计:它不不断地检查数据是否已经改变,而是当数据改变时,系统会得到通知,并采取相应的行动。 

数据库中的读写分离

这个对于公共耦合的改进让作者瞬间意识到数据库中的读写分离机制! 进一步讨论:

  • 公共耦合主要发生在多个模块或应用共享相同的数据库表或字段时。这意味着,如果一个模块对共享数据结构进行了修改(例如更改了表结构或删除了某些字段),其他模块可能会受到影响。

  • 读写分离是数据库架构中的一个策略,主要目的是提高性能和扩展性。在读写分离的系统中,写入操作通常发送到主数据库,而读取操作可以从一个或多个从数据库进行。

  • 读写分离可以降低公共耦合,因为它使得读和写操作在逻辑上或物理上分离,减少了对同一数据的并发访问。但是,它并不完全消除公共耦合,特别是在需要保持数据一致性的情况下。

读写分离如何帮助
  1. 减少资源竞争由于写操作通常只发生在主数据库上,而读操作可以在多个从数据库上分散,这减少了对同一数据资源的并发访问,从而降低了因并发访问导致的数据不一致性的风险。

  2. 分离业务逻辑:在某些场景中,可能会有一个模块主要进行数据写入,而其他模块主要进行数据读取。这就是上图改进后的效果。读写分离自然地分隔了读写这两种业务逻辑,减少了它们之间的直接依赖。

但是,读写分离不能完全消除公共耦合,原因如下:

  1. 结构共享仍然存在尽管读和写操作已经分离,但如果多个模块共享相同的数据结构,它们仍然是耦合的。例如,如果更改了数据库的表结构,那么与该表相关的所有读写模块都可能受到影响。

  2. 数据同步和一致性:在读写分离的环境中,从数据库需要定期从主数据库同步数据。这可能导致短暂的数据不一致。因此,模块需要考虑这种不一致性,特别是在高数据更新频率的应用中。


内容耦合

1. goto就是一种通过非正常路口随便进入另一个模块内部的方法,会造成内容耦合。但是goto语句会在极端情况下对性能做出优化,所以到现在仍然允许使用,只不过需要强劲的实力。

2. 一个模块有多个入口,其实也会违背controlled interface的机制,接口不唯一了。

3. 模块代码重叠,可以通过将重叠部分(中间图阴影部分所示)转换成可调用的部分。

数据库视图

对于内容耦合,作者认为可以通过视图view这一机制降低。

数据库中的视图(view)可以帮助管理和降低内容耦合。内容耦合发生在一个模块直接访问另一个模块的内部数据或实现细节。在数据库上下文中,这可以解释为应用或服务直接访问数据库表的具体结构和数据。

使用视图(views)具有以下优势:

  1. 抽象:视图提供了一个对基础数据的抽象表示。它们允许展现数据的特定部分,或者以不同的方式整合和呈现数据,而不需要改变基础的表结构。

  2. 隔离变化:如果基础表的结构需要更改,视图可以帮助保持对外部应用或服务的相同表示,只要视图的定义和输出仍然是一致的。

  3. 安全通过视图,可以控制对数据的访问,只显示对特定应用或服务的必要数据,从而提高数据的安全性。

  4. 简化复杂查询:对于复杂的数据结构,您可以创建视图来简化查询,使得应用的查询逻辑更加简单和直接。

通过这些方式,视图确实可以降低内容耦合,因为它们为应用程序提供了一个与基础数据结构和逻辑解耦的数据访问层。然而,值得注意的是,使用视图并不完全消除耦合,因为任何对视图定义的更改仍然可能影响到依赖它的应用程序。


在实践中要注意分析耦合情况,分析模块,对模块进行调整。

逻辑内聚往往与控制耦合相关!内聚部分下周再讲解。

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

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

相关文章

springboot自动配置原理面试题(自用)

springboot自动装配主要是基于注解编程和约定大于配置的思想设计 核心步骤: 1 组件必须包含configuration并声明为bean注解返回注入到IOC容器中 2 第三方jar包,根据/meta-inf/目录下增加spring.factories文件加载配置文件中的内容 3 springboot获取到…

NSSCTF做题(9)

[GDOUCTF 2023]<ez_ze> 看见输入框而且有提示说是ssti注入 输入{{7*7}} 试试&#xff0c;发现报错 输入{%%}发现了是jinja2模板 找到关键函数 Python SSTI利用jinja过滤器进行Bypass ph0ebuss Blog 原理见这篇文章&#xff0c;这里直接给出payload {%set ninedict(aaa…

3.1 SQL概述

思维导图&#xff1a; 前言&#xff1a; 前言笔记&#xff1a;第3章 关系数据库标准语言SQL - **SQL的定义**&#xff1a; - 关系数据库的标准和通用语言。 - 功能强大&#xff0c;不仅限于查询。 - 功能覆盖&#xff1a;数据库模式创建、数据插入/修改、数据库安全性与…

LeetCode 1095. 山脉数组中查找目标值【数组,二分】1827

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

OOA/D 时统一过程(UP)中的 迭代、 进化 和 敏捷

一、迭代和进化式开发的优势 相对于顺序或“瀑布”软件开发模型&#xff0c;迭代和进化式开发&#xff08;iterative and evolutionary development &#xff09;对部分系统及早地引入了编程和测试&#xff0c;并重复这一循环。这种方式通常会还没有详细定义所有需求的情况下假…

如何使用前端构建工具(如Webpack、Parcel)?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

C++指针解读(6)-- 指针和字符串

1、字符串的基本概念 &#xff08;1&#xff09;字符串的存储 字符串是存放在字符数组中的。比如字符串“hello”&#xff0c;在内存中是这么存放的&#xff1a; 这里要注意&#xff0c;在字符串的最后会加上一个\0&#xff0c;也被称为NUL字符&#xff0c;表示字符串的结束位…

Liunx中系统安全及文件系统(极其粗糙版)

系统安全&#xff1a; 系统安全和数据防护&#xff0c;数据备份的资质 比如三台服务器&#xff1a; 500万 工信部是有要求的&#xff0c;组织必须保证处理的个人数据的安全性 品牌形象如何维护呢 基于liunx的安全加固措施&#xff1a; 权限进行控制 账号安全&#xff1a;…

09_Webpack打包工具

1 初识Webpack 1.1 什么是Webpack Webpack打包工具对项目中的复杂文件进行打包处理&#xff0c;可以实现项目的自动化构建&#xff0c;并且给前端开发人员带来了极大的便利。 目前&#xff0c;企业中的绝大多数前端项目是基于Webpack打包工具来进行开发的。 1.2 Webpack的安…

C++学习——引用详解

以下内容源于C语言中文网的学习与整理&#xff0c;非原创&#xff0c;如有侵权请告知删除。 一、引用的语法 1、引用的含义 引用&#xff08;Reference&#xff09;是 C 相对于C语言的又一个扩充。 引用可以看做是数据的一个别名&#xff0c;通过这个别名和原来的名字都能够…

可观测 AIOps 的智能监控和诊断实践丨QCon 全球软件开发大会总结

作者&#xff1a;董善东&#xff08;梵登&#xff09; 本文是作者于 9 月 5 日在 QCon 北京 2023&#xff08;全球软件开发大会&#xff09;上做的《阿里云可观测 AIOps 的智能监控和诊断实践》专题演讲文字版。 大家上午好&#xff0c;很高兴可以在 QCon 稳定性和可观测的场…

华为云云耀云服务器L实例评测|华为云耀云服务器L实例评测用例(五)

六、华为云耀云服务器L实例评测用例&#xff1a; “兵马未动&#xff0c;粮草先行”&#xff0c;随着企业业务的快速发展&#xff0c;服务器在数字化建设体系至关重要&#xff0c;为了保证服务器的稳定性、可靠性&#xff0c;需要对服务器进行评测&#xff0c;以确保服务器能够…

FPC柔性电路板介绍及PCB设计经验规则总结

🏡《总目录》 目录 1,概述2,FPC的特点3,FPC设计十五条经验规则4,总结1,概述 FPC软板由于具有可弯曲折叠的特点,当前在消费电子,汽车电子和航空航天领域应用广泛。本文详细介绍FPC的特点并对FPC板设计中需要注意的经验原则进行总结。 2,FPC的特点 FPC的全称是Flexibl…

网站如何应对网络流量攻击

网络安全问题中&#xff0c;受到流量攻击是一种常见挑战。以下是一系列的专业建议&#xff0c;帮助您预防和减轻这类攻击&#xff0c;从而确保您的网站和数据的安全。 使用 Web 应用程序防火墙 (WAF) Web 应用程序防火墙是一项专门的安全工具&#xff0c;能够检测和拦截恶意流…

【Docker 内核详解】namespace 资源隔离(五):User namespaces

【Docker 内核详解 - namespace 资源隔离】系列包含&#xff1a; namespace 资源隔离&#xff08;一&#xff09;&#xff1a;进行 namespace API 操作的 4 种方式namespace 资源隔离&#xff08;二&#xff09;&#xff1a;UTS namespace & IPC namespacenamespace 资源隔…

项目管理软件中注释功能的作用是什么?

在项目管理软件中&#xff0c;注释功能允许您对任务、文件夹和项目进行详细的标注。这一功能不仅便于团队成员之间的沟通与协作&#xff0c;还能提高项目管理的效率。通过在项目中添加评论&#xff0c;您可以及时了解项目的最新动态&#xff0c;提出疑问并寻求解决方案。此外&a…

汇编语言基础

引言 汇编语言是直接在硬件之上工作的编程语言&#xff0c;首先要了解硬件系统的结构&#xff0c;才能有效的应用汇编语言对其编程。汇编课程的研究重点放在如何利用硬件系统的编程结构和指令集有效灵活的控制系统进行工作。 基础知识 1.1机器语言 机器语言是机器指令的集合…

单链表---结构体实现

定义 链表称为线性表的链式存储&#xff0c;顺序表逻辑上相邻的数据&#xff0c;存储位置也相邻。链表逻辑上相邻的数据&#xff0c;存储位置是随机分布在内存的各个位置上的。 故 对于每一个结点&#xff0c;定义的结构体是&#xff1a; typedef struct _LinkNode {int d…

Java-使用sqlSessionTemplate实现批量更新-模拟mybatis 动态sql

环境准备&#xff08;非核心方法&#xff09; 创建表 创建表的sql(下表是基于Oracle创建的) CREATE TABLE "SYSTEM"."STUDENT" ("ID" NUMBER(10, 0),"NAME" VARCHAR2(20 BYTE),"ADDRES" CLOB,PRIMARY KEY ( …

milvus和相似度检索

流程 milvus的使用流程是 创建collection -> 创建partition -> 创建索引(如果需要检索) -> 插入数据 -> 检索 这里以Python为例, 使用的milvus版本为2.3.x 首先按照库&#xff0c; python3 -m pip install pymilvus Connect from pymilvus import connections c…