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

设计心得——分层和划分模块

一、分层

在实际的设计开发过程中,对于稍微大一些的项目,基本都涉及到分层。什么是分层呢?其实非常简单,就是利用某种逻辑或域的范围等把整个项目划分成多个层次。它们之间通过接口(可能是简单的函数接口也可以是服务等)进行通信。分层地目的其实非常明显,就是为了整个设计的解耦和重用,使得整个项目结构更清晰和控制更合理,也便 于后期的维护和扩展。
一般来说,分层是在更高层次上进行抽象,它属于对整个项目的横向切分。分层的优点非常多,比如高内聚、低耦合以及便于维护和接口扩展,提供了更好的技术更新接口等等。但在明白其的优势之后,更要明白它的劣势所在:
1、降低性能
增加层次的最主要的问题就是导致一定的性能损失。毕竟大家都明白,直接调用比通过接口处理一下,理论上一定是要快的。特别是在通信量巨大并且并发较高的情况下,其性能的损失会非常的明显。
2、增加复杂性
分层设计需要进行良好的层间接口设计,否则极有可能导致因为接口的问题导致层间的通信问题,比如对于一个任务是需要调用一个接口完成(单一原则)还是一个以上接口(效率)实现呢?这就需要设计者不断的根据实际情况进行调整。
3、工程化的风险
设计者们往往有一个爱好,一旦觉得某项技术不错,便会不断的在这个基础上进行强化,也就是过度设计。体现在分层上就是更乐意通过分层来解决很多问题。虽然分层在很多情况下可以将问题简化,但过多的引入分层等于变相的增加了另外一种复杂性。也就是说,设计者一定要明白,分层的适度性和科学性。而且过多的分层往往导致测试的复杂性和增加测试的难度。

虽然明白了分层的优势,但说起分层来大家可能有点熟悉又陌生的感觉,其实举一个常见的MVC的例子大家就明白了,它其实就是把整个程序分成了三层,上层的表示层用来处理接收的输入数据和处理后返回的数据;中间的控制层用来进行上下的交互数据管理;而最下面的模型层则进行数据的最终存储逻辑控制。
通过MVC明白了这种分层的设计的具像化,那么其它也就好理解了,比如常见的另外一种分层,网络分层,TCP/IP的分层等等。某些情况下,分层类似于见到的过滤器,一层层的过滤掉不同的物质(或者说一层只处理一个或几个业务)。这样,大家应该就对分层有了一个很显性的认识。
但需要注意的是,软件设计的分层往往从不同的角度看有不同的理解,大家不要教条和僵化,慢慢思考、理解和学习即可。

二、模块化

说了分层,再说设计高频遇到的名词,模块。其实模块这个概念就是一组功能相近的软件代码或组件。这里面水儿深着哪。首先,什么是一组,另外什么是功能相近?什么是代码或组件?这个其实没有强制的定义。给大家举个例子,一个函数就有可能是一个模块,而一个类也可能是一个模块,一个文档可能也是。一个软件可能也是…凡此种种。而模块化就是以模块为基础的设计方式。
模块会根据场景不一致而呈现中不同的情况。而上面所提到的功能相近等其实也可以站不同的角度和层次上来看。再举一个例子,一个大型的变电站运行软件,可能分成服务端软件,客户端软件,移动端软件和设备端软件等等。那么从这个角度来看,它们每个都算是一个独立的模块。一般来说,模块属于是在纵向上的划分,即更强功能的组合。
需要提醒的是,不要混淆模块的一些概念,比如在不少的程序语言中,都有模块这个概念。它们和设计中提到的模块基本类似,但也有着一些显著的不同。切记。
模块化设计的优点很多,和分层差不多,毕竟二者都是朝着同一个目的而来的。
模块化设计的主要优点包括:高内聚,低耦合,接口清晰,易维护,方便代码重用及团队协作。但它的缺点也不少:
1、模块化设计增加了设计的难度
不是每个设计者都能很好的把握模块的设计,这就可能导致模块设计的不合理性,进而导致各种问题。
2、降低效率
和分层一样,通过接口调用的模块,理论上会降低整体的效率
3、工程上的过度设计
一如分层,模块的过度设计,同样会导致整个软件的难于控制,过多的模块往往使得业务的碎片化;而过少的模块除了引入了一些复杂性,几乎没有体现出模块的优势。
4、模块的维护
设计完成的模块,需要从开始到结束都一套完善的管理流程,包括文档、工具等。如果开发者们没有按照设计要求进行,则可能导致引入不少的风险。最简单的例子就是不同的模块间,使用了不同的技术标准实现或者引入不相同功能的不同版本的库。都可能导致问题的出现,而且极有可能很难发现问题的原因。
但正如成语说得好,不能“因噎废食”。设计就是一种取舍和妥协!

三、二者关系

在分析了上述的分层和模块后,不少的新手可能会有一个疑问,怎么看待二者的设计上的抽象的不同呢?一般情况下,分层的抽象是高于模块的抽象的,但具体情况上则有可能有所不同 。比如在上面提到的变电站软件中,每个模块中,可能又会划分成不同的层次。这样看来,模块包含着分层。也就是说,实际应用中,分层和模块间没有明确的界限,二者可以互相包容。
其实,稍微大一些软件的设计,一般来说是分层优先,然后进行模块划分。经常可以看到系统的整体设计架构图,就是这样的。但凡是都有例外,分层和模块二者之间其实是一个互相补充互相协作上的抽象关系。从整体抽象看,分层是较大粒度的划分而模块则是较小粒度的划分。也即上面提到的分层是基于横向的水平划分而模块是基于纵向的垂直划分。
一般的情况下,分好的层次中,每层都包含若干个模块。模块间以接口通信,整合后通过层间的接口再与其它层进行通信。层次之间的数据依赖单向为主,但模块间的依赖则灵活很多。

四、二者的应用

分层和模块化的应用场景在不少的场景下是重叠的,但整体上来看,还是可以进行区别划分的。
1、分层的应用
a) 大规模的应用,特别是企业级的应用。包括框架、库和系统等
b) 分布式应用,为更好的协调分布式各个节点间的通信,分层是一个非常好的设计思路
c) Web应用,这个更容易理解,常见的MVC设计在Web服务中体现的最明显
d) 复杂应用,对业务或逻辑处理深度较大,恰恰是分层设计的良好应用场景
e) 其它一些特殊场景

2、模块化的应用
模块化设计几乎是所有的程序设计都离不开的。除非程序很小或者说一些例程,正常情况下,一个软件都要进行模块化的设计。

五、总结

设计一个从抽象到具体,从整体到细节,不断具体而微的过程。俗话说得好“教的曲儿唱不得”。设计不像技巧,多问两下多看两下代码就会用了。所以设计中的一些具体的手段和方法,要不断的从不同的角度不同的场景进行分析学习,并不断在实践中进行检验。反思得失,总结教训,形成自己的一套解决问题、处理问题的逻辑和流程。最终升华为自己的设计思想。
这一定是一个长期的,不断的否定之否定的过程!愿与诸君共勉!

相关文章:

设计心得——分层和划分模块

一、分层 在实际的设计开发过程中,对于稍微大一些的项目,基本都涉及到分层。什么是分层呢?其实非常简单,就是利用某种逻辑或域的范围等把整个项目划分成多个层次。它们之间通过接口(可能是简单的函数接口也可以是服务…...

uniapp使用蓝牙,usb,局域网,打印机打印

使用流程(支持安卓和iOS) 引入SDK 引入原生插件包地址如下 https://github.com/oldfive20250214/UniPrinterDemo 连接设备 安卓支持经典蓝牙、ble蓝牙、usb、局域网(参考API) iOS支持ble蓝牙、局域网(参考API&…...

PQL查询和监控各类中间件

1 prometheus的PQL查询 1.1 Metrics数据介绍 prometheus监控中采集过来的数据统一称为Metrics数据,其并不是代表具体的数据格式,而是一种统计度量计算单位当需要为某个系统或者某个服务做监控时,就需要使用到 metrics prometheus支持的met…...

day1 redis登入指令

[rootlocalhost data]# redis-cli -h ip -p 6379 -a q123q123 Warning: Using a password with -a or -u option on the command line interface may not be safe. ip:6379> 以上, Bigder...

2025 年 AI 网络安全预测

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 微软和 OpenAI 宣布延长战略合作伙伴关系,加强对推进人工智能技术的承诺,这表明强大的 AI 将在未来占据主导地位。 随着人工智能 &#x…...

[Windows] 多系统键鼠共享工具 轻松跨系统控制多台电脑

参考原文:[Windows] 多系统键鼠共享工具 轻松跨系统控制多台电脑 还在为多台电脑需要多套键盘鼠标而烦恼吗?是不是在操控 Windows、macOS、Linux 不同系统电脑时手忙脚乱?现在,这些问题通通能解决!Deskflow 软件闪亮登…...

单片机的发展

一、引言 单片机自诞生以来,经历了四十多年的风风雨雨,从最初的工业控制逐步扩展到家电、通信、智能家居等各个领域。其发展过程就像是一场精彩的冒险,每一次技术的革新都像是在未知的海域中开辟新的航线。 二、单片机的发展历程 &#xff…...

Spring 构造器注入和setter注入的比较

一、比较说明 在 Spring 框架中,构造器注入(Constructor Injection)和 Setter 注入(Setter Injection)是实现依赖注入(DI)的两种主要方式。它们的核心区别在于依赖注入的时机、代码设计理念以及…...

uploadlabs通关思路

目录 靶场准备 复现 pass-01 代码审计 执行逻辑 文件上传 方法一:直接修改或删除js脚本 方法二:修改文件后缀 pass-02 代码审计 文件上传 1. 思路 2. 实操 pass-03 代码审计 过程: 文件上传 pass-04 代码审计 文件上传 p…...

迷你世界脚本自定义UI接口:Customui

自定义UI接口:Customui 彼得兔 更新时间: 2024-11-07 15:12:42 具体函数名及描述如下:(除前两个,其余的目前只能在UI编辑器内部的脚本使用) 序号 函数名 函数描述 1 openUIView(...) 打开一个UI界面(注意…...

【情境领导者】评估情境——准备度水平

本系列是看了《情境领导者》一书,结合自己工作的实践经验所做的学习笔记。 在文章【情境领导者】评估情境——什么是准备度-CSDN博客我们提到准备度是由能力和意愿两部分组成的。 准备度水平 而我们要怎么去评估准备度呢?准备度水平是指人们在每项工作中…...

2025 ubuntu24.04系统安装docker

1.查看ubuntu版本(Ubuntu 24.04 LTS) rootmaster:~# cat /etc/os-release PRETTY_NAME"Ubuntu 24.04 LTS" NAME"Ubuntu" VERSION_ID"24.04" VERSION"24.04 LTS (Noble Numbat)" VERSION_CODENAMEnoble IDubun…...

Android中AIDL和HIDL的区别

在Android中,AIDL(Android Interface Definition Language) 和 HIDL(HAL Interface Definition Language) 是两种用于定义跨进程通信接口的语言。AIDL 是 Android 系统最早支持的 IPC(进程间通信&#xff0…...

通过数据库网格架构构建现代分布式数据系统

在当今微服务驱动的世界中,企业在跨分布式系统管理数据方面面临着越来越多的挑战。数据库网格架构已成为应对这些挑战的强大解决方案,它提供了一种与现代应用架构相匹配的分散式数据管理方法。本文将探讨数据库网格架构的工作原理,以及如何使…...

Python基于Django的医用耗材网上申领系统【附源码、文档说明】

博主介绍:✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&…...

Python爬虫实战:一键采集电商数据,掌握市场动态!

电商数据分析是个香饽饽,可市面上的数据采集工具要不贵得吓人,要不就是各种广告弹窗。干脆自己动手写个爬虫,想抓啥抓啥,还能学点技术。今天咱聊聊怎么用Python写个简单的电商数据爬虫。 打好基础:搞定请求头 别看爬虫…...

STM32之I2C硬件外设

注意:硬件I2C的引脚是固定的 SDA和SCL都是复用到外部引脚。 SDA发送时数据寄存器的数据在数据移位寄存器空闲的状态下进入数据移位寄存器,此时会置状态寄存器的TXE为1,表示发送寄存器为空,然后往数据控制寄存器中一位一位的移送数…...

【C++】中的赋值初始化和直接初始化的区别

在C中,赋值初始化(也称为拷贝初始化)和直接初始化(也称为构造初始化)虽然常常产生相同的结果,但在某些情况下它们有不同的含义和行为。 赋值初始化(Copy Initialization) 使用等号…...

Python ❀ Unix时间戳转日期或日期转时间戳工具分享

设计一款Unix时间戳和日期转换工具,其代码如下: from datetime import datetimeclass Change_Date_Time(object):def __init__(self, date_strNone, date_numNone):self.date_str date_strself.date_num date_num# 转时间戳def datetime2timestamp(s…...

本地部署Dify及避坑指南

Dify作为开源的大模型应用开发平台,支持本地私有化部署,既能保障数据安全,又能实现灵活定制。但对于新手而言,从环境配置到服务启动可能面临诸多挑战。本文结合实战经验,手把手教你从零部署Dify,并总结高频…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络&#xf…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则&#xf…...

网站指纹识别

网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...