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

【高内聚】设计模式是如何让软件更好做到高内聚的?

高内聚(High Cohesion)是指模块内部的元素紧密协作,共同完成一个明确且相对独立的功能。就像高效的小团队,成员们目标一致,相互配合默契。
低耦合(Loose Coupling)是指模块之间的依赖较少,只通过精心定义的接口与外部交互。这样的设计使得模块对外界的依赖减少,从而提高了系统的灵活性和可维护性。
高内聚是“解耦”的关键,原因在于当模块具有高内聚性时,它自身形成了一个功能完整的单元。这样的模块对外的依赖较少,只需调用其接口即可实现功能,而不需要了解其内部复杂的细节

通过降低模块之间的相互关联和依赖,可以达到解耦的效果。这样,当一个模块发生变化时,不会影响到其他模块的核心功能,也不会产生过多的连锁反应,进一步促进了系统的稳定和解耦。
总的来说,高内聚和低耦合是软件设计中追求的目标,它们有助于提高系统的灵活性、可维护性和稳定性

首先,我会描述一个场景,然后提供两种设计方案:一种是低内聚的设计,另一种是高内聚的设计。我会用mermaid图例来展示这两种设计,并使用表格来对比它们的优缺点。

案例1:短信发送

低内聚设计方案

如果客户端直接集成对接三种客户端(移动、电信、联通),那将是一个低内聚的设计。在这种情况下,客户端需要处理与三个不同短信客户端的交互,这将导致客户端的职责过多,从而降低其内聚性。

发送短信
发送短信
发送短信
处理短信
处理短信
处理短信
客户端
移动短信客户端
电信短信客户端
联通短信客户端
移动
电信
联通
  1. 客户端:直接与移动、电信、联通的短信客户端交互。
  2. 移动/电信/联通短信客户端:分别接收来自客户端的短信,并处理与各自运营商相关的逻辑。

高内聚设计方案

这种设计模式属于中介者模式(Mediator Pattern)。中介者模式是一种行为设计模式,它通过引入一个中介对象(在这个案例中是短信门户)来封装一系列对象之间的交互。这种模式使得对象之间不再直接通信,而是通过中介者对象来进行交互,从而降低了对象之间的耦合度。
短信门户作为中介者,负责协调客户端和不同运营商网关之间的通信。客户端不需要直接知道网关的细节,只需要将短信发送给短信门户,由短信门户负责将短信转发给适当的网关。这样的设计使得系统更加灵活,易于扩展和维护。

发送短信
分发短信
分发短信
分发短信
发送短信
发送短信
发送短信
客户端
短信门户
移动网关
电信网关
联通网关
移动短信客户端
电信短信客户端
联通短信客户端
  1. 客户端:只负责发送短信到短信门户。
  2. 短信门户:负责接收客户端的短信,并根据运营商将短信分发到相应的短信网关。
  3. 短信网关:分别与移动、电信、联通的短信客户端交互,负责将短信发送到正确的运营商。

对比分析

特性低内聚设计高内聚设计
可维护性低:客户端需要处理与多个运营商客户端的交互,维护复杂度高。高:客户端只与短信门户交互,短信门户负责与运营商客户端的交互,维护简单。
可扩展性低:添加新运营商时,需要修改客户端代码。高:添加新运营商时,只需在短信门户中添加新网关,无需修改客户端代码。
可读性低:客户端承担了过多的职责,难以理解。高:每个组件都有明确的职责,易于理解和阅读。
内聚性低:客户端职责过多,内聚性低。高:每个组件都有明确的、单一的职责,内聚性高。
复用性低:客户端与特定运营商紧密耦合,难以复用。高:短信门户和短信网关可以独立于客户端和运营商客户端复用。

通过这个对比,我们可以看到高内聚设计在可维护性、可扩展性、可读性和复用性方面都优于低内聚设计。高内聚设计通过将功能分解为更小的、更专注的组件,使得系统更加模块化和灵活。

案例2:库存管理

假设我们正在设计一个简单的库存管理系统。这个系统需要处理两种主要操作:添加新商品到库存中和对现有商品进行库存更新。

低内聚设计方案

在低内聚的设计中,所有功能可能都集中在一个大的类或模块中。这个类负责添加新商品、更新库存、处理用户输入等所有任务。

manages
InventoryManager
-inventory: Map
+addProduct(product: Product)
+updateStock(productId: string, quantity: number)
+handleUserInput(input: string)
Product
+id: string
+name: string
+quantity: number

高内聚设计方案

在高内聚的设计中,我们使用了单一职责原则(Single Responsibility Principle),这是面向对象设计中的五个基本原则(SOLID)之一。单一职责原则指出,一个类应该只有一个引起它变化的原因。这意味着一个类应该只负责一项功能或职责。我们将功能分解为更小的、更专注于特定任务的类。例如,我们可以有一个类专门负责处理库存,另一个类专门处理用户输入。

manages
interacts with
InventoryManager
-inventory: Map
+addProduct(product: Product)
+updateStock(productId: string, quantity: number)
UserManager
+handleUserInput(input: string)
Product
+id: string
+name: string
+quantity: number

对比表格

特性低内聚设计高内聚设计
可维护性低:所有功能集中在一个类中,修改困难高:功能分散在多个类中,易于维护和修改
可扩展性低:添加新功能可能需要修改整个类高:可以轻松添加新类和功能,无需修改现有代码
可读性低:类过于庞大,难以理解高:每个类都有明确的职责,易于理解和阅读
内聚性低:类承担了过多的职责高:每个类都有明确的、单一的职责
复用性低:类过于特定,难以在其他场景中复用高:更通用的类可以在其他项目中复用

通过这个案例,我们可以看到高内聚设计在可维护性、可扩展性、可读性和复用性方面都优于低内聚设计。高内聚设计通过将功能分解为更小的、更专注的类,使得系统更加模块化和灵活。

相关文章:

【高内聚】设计模式是如何让软件更好做到高内聚的?

高内聚(High Cohesion)是指模块内部的元素紧密协作,共同完成一个明确且相对独立的功能。就像高效的小团队,成员们目标一致,相互配合默契。 低耦合(Loose Coupling)是指模块之间的依赖较少&#…...

10.2 目录(文件夹)操作

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 10.2.1 DirectoryInfo类 DirectoryInfo类可以获得目录信息。 DirectoryInfo常用属性: Name:获取Director…...

LiteFlow Spring boot使用方式

文章目录 概述LiteFlow框架的优势规则调用逻辑规则组件定义组件内数据获取通过 DefaultContext自定义上下文 通过 组件规则定义数据通过预先传入数据 liteflow 使用 概述 在每个公司的系统中,总有一些拥有复杂业务逻辑的系统,这些系统承载着核心业务逻…...

OSCP:Windows 服务提权详解

在Windows操作系统中,服务是一种特殊的后台进程,它们通常以较高的权限(如 SYSTEM 或 Administrator)运行。攻击者可以通过控制服务的创建、配置或运行过程实现权限提升(提权)。本文将详细分析Windows服务提…...

星火大模型接入及文本生成HTTP流式、非流式接口(JAVA)

文章目录 一、接入星火大模型二、基于JAVA实现HTTP非流式接口1.配置2.接口实现(1)分析接口请求(2)代码实现 3.功能测试(1)测试对话功能(2)测试记住上下文功能 三、基于JAVA实现HTTP流…...

21.Word:小赵-毕业论文排版❗【39】

目录 题目​ NO1.2 NO3.4 NO5.6 NO7.8.9 NO10.11.12 题目 NO1.2 自己的论文当中接收老师的修改:审阅→比较→源文档:考生文件夹:Word.docx→修订的文档:考生文件夹:教师修改→确定→接收→接收所有修订将合并之…...

Python中的函数(上)

Python中的函数是非常重要的编程概念,以下是详细的介绍: 函数定义基础 在Python中,函数是组织好的、可重复使用的代码块,用于执行特定任务。通过函数,我们可以将复杂的程序分解为较小的、更易管理的部分&#xff0c…...

Windows11 安装poetry

使用powershell安装 (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py - 如果使用py运行失败则替换为python即可 终端运行结果如下 D:\AI\A_Share_investment_Agent> (Invoke-WebRequest -Uri https://install.python-poetry.…...

浅谈Linux 权限、压缩、进程与服务

概述 放假回家,对Linux系统的一些知识进行重新的整理,做到温故而知新,对用户权限管理、文件赋权、压缩文件、进程与服务的知识进行了一次梳理和总结。 权限管理 Linux最基础的权限是用户和文件,先了解基础的用户权限和文件权限…...

006 LocalStorage和SessionStorage

JWT存储在LocalStorage与SessionStorage里的区别和共同点如下: 区别 数据有效期: • LocalStorage:始终有效,存储的数据会一直保留在浏览器中,即使窗口或浏览器关闭也一直保存,因此常用作持久数据。 • Se…...

AJAX RSS Reader:技术解析与应用场景

AJAX RSS Reader:技术解析与应用场景 引言 随着互联网的快速发展,信息量呈爆炸式增长。为了方便用户快速获取感兴趣的信息,RSS(Really Simple Syndication)技术应运而生。AJAX RSS Reader作为一种基于AJAX技术的信息读取工具,在用户体验和信息获取方面具有显著优势。本…...

Go优雅实现redis分布式锁

前言 系统为了保证高可用,通常会部署多实例,并且会存在同时对共享资源并发读写,这时候为了保证读写的安全,常规手段是会引入分布式锁,本文将介绍如何使用redis设计一个优雅的Go分布式锁。 设计 redis分布式锁是借助…...

本地部署deepseek模型步骤

文章目录 0.deepseek简介1.安装ollama软件2.配置合适的deepseek模型3.安装chatbox可视化 0.deepseek简介 DeepSeek 是一家专注于人工智能技术研发的公司,致力于打造高性能、低成本的 AI 模型,其目标是让 AI 技术更加普惠,让更多人能够用上强…...

(2025 年最新)MacOS Redis Desktop Manager中文版下载,附详细图文

MacOS Redis Desktop Manager中文版下载 大家好,今天给大家带来一款非常实用的 Redis 可视化工具——Redis Desktop Manager(简称 RDM)。相信很多开发者都用过 Redis 数据库,但如果你想要更高效、更方便地管理 Redis 数据&#x…...

C++ 写一个简单的加减法计算器

************* C topic:结构 ************* Structure is a very intersting issue. I really dont like concepts as it is boring. I would like to cases instead. If I want to learn something, donot hesitate to make shits. Like building a house. Wh…...

计算机网络基础 - 链路层(3)

计算机网络基础 链路层和局域网交换局域网链路层寻址地址解析协议 ARP以太网物理拓扑以太网帧结构以太网提供的服务以太网标准 链路层交换机交换机转发和过滤自学习交换机优点交换机和路由器比较 大家好呀!我是小笙,本章我主要分享计算机网络基础 - 链路…...

ray.rllib 入门实践-5: 训练算法

前面的博客介绍了ray.rllib中算法的配置和构建,也包含了算法训练的代码。 但是rllib中实现算法训练的方式不止一种,本博客对此进行介绍。很多教程使用 PPOTrainer 进行训练,但是 PPOTrainer 在最近的 ray 版本中已经取消了。 环境配置&#x…...

FPGA 使用 CLOCK_LOW_FANOUT 约束

使用 CLOCK_LOW_FANOUT 约束 您可以使用 CLOCK_LOW_FANOUT 约束在单个时钟区域中包含时钟缓存负载。在由全局时钟缓存直接驱动的时钟网段 上对 CLOCK_LOW_FANOUT 进行设置,而且全局时钟缓存扇出必须低于 2000 个负载。 注释: 当与其他时钟约束配合…...

选择的阶段性质疑

条条大路通罗马,每个人选择的道路,方向并不一样,但不妨碍都可以到达终点,而往往大家会更推崇自己走过的路径。 自己靠什么走向成功,自己用了什么方法,奉行什么原则或者理念,也会尽可能传播这种&…...

固有频率与模态分析

目录 引言 1. 固有频率:物体的“天生节奏” 1.1 定义 1.2 关键特点 1.3 实际意义 2. 有限元中的模态分析:给结构“体检振动” 2.1 模态分析的意义 2.2 实际案例 2.2.1 桥梁模态分析 2.2.2 飞机机翼模态分析 2.2.3 具体事例 3. 模态分析的工具…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

dify打造数据可视化图表

一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...