软件设计到底是什么?

news2024/11/17 3:01:40

软件设计是什么:

  • 就是讨论要用什么技术实现功能?
  • 就是要考虑选择哪些框架和中间件?
  • 设计就是设计模式?
  • 设计就是Controller、Service加Model?
  • ……

一百个程序员,就有一百种理解。若按照这些方式去了解“软件设计”,软件设计的知识不仅散乱,且像陷入沼泽:

  • 刚学会Java,听说Go成了新的主流,还没等下决心转语言 ,Rust现在又被吹起来
  • 终于知道MQ能干啥了,准备从众学习Kafka,这时又看到一篇公众号说Pulsar比Kafka更好
  • 总算理解观察者模式,却有人告诉你JDK中早就提供了原生支持,但更好的做法是Guava EventBus
  • 好不容易弄清MVC,却发现后端现在的主要工作是写RESTful服务,Controller还没有用,就该改名Resource
    ……

软件设计应关注长期变化,能应对需求规模的膨胀。然而这些在不断变化的东西可能还没你的软件生命周期长,又怎能支撑长久的变化?那软件设计到底是什么?

1 核心模型

软件开发是解决由需求带来的各种问题,解决结果是可运行的交付物。如在线购物的需求,使用电商平台方案解决。软件设计就是在需求和解决方案之间架设的一个桥梁。

区别于解决简单的问题,软件开发往往是一项长期工作,是个多人运动。这就需要建立起统一的结构,以便所有人都能有共同理解。就像建筑中的图纸,懂建筑的人看了后,就会产生一个统一认知。

而在软件开发过程中,这种统一结构就是模型,软件设计就是要构建一套模型
模型包括:

  • 描述业务的各种实体
  • 完成业务功能的各种组件

写代码中常用的服务(Service)、调度器(Scheduler)等概念就是一个个模型。模型是一个软件的骨架,也是一个软件之所以是这个软件的核心。一个电商平台,它不用关系型DB,还可用NoSQL,但若无产品信息,没有订单,它就肯定不是电商平台。

模型粒度可大可小。若把模型理解为一个个类,就是小模型。也可把整个系统当作一个整体,就是大模型。“高内聚、低耦合”就是对模型的要求
这种模型有效隐藏细节,理解更容易,可继续扩展。如程序设计语言,就是提供编程模型,让我们写程序不用再面对各种硬件差异,还能够在此基础上继续提供新功能。各种框架和技术,也是提供了一个个模型,它们大幅降低了开发门槛。

所以整个计算机世界就是在这样一个又一个模型的叠加中,一点点构建。模型是分层的,就像乐高,由一个个小块构建出一个个大部件,再用这些部件组成成品。
与一些人理解的Controller、Service分层有差异。这才是在计算机行业中普遍存在的分层。网络模型就是典型分层模型。按TCP/IP分层,网络层要构建在网络接口层上,应用层要依赖传输层。
即便是在一个软件内部,模型也可分层。可以先从最核心的模型开始构建,有了这个核心模型后,可通过组合这些基础的模型,构建出上一层模型。

如交易系统设计。分析主要交易动作后,提出一个交易原语概念,包括资产冻结、解冻、出金、入金等动作。然后,把原先的交易动作变成了原语的组合。如下单是资产冻结,成交是不同账户的出金和入金,撤单则是资产解冻:

由:

  • 交易原语保证每个业务的准确性
  • 交易动作保证整个操作的事务性

这就是模型的分层。所以,模型是一个软件核心;模型粒度可大可小;好模型“高内聚、低耦合”;模型可分层,由底层的模型提供接口,构建出上层的模型。

仅是把软件设计理解成构建模型还不够。模型设计也不能任意妄为,需要有一定约束,即软件设计要构建的另一部分:规范。

2 约束的规范

限定什么样的需求应该以怎样方式完成。如:

  • 业务处理相关代码,体现在领域模型
  • 网络连接相关代码,写在网关
  • 与外部系统集成的代码,要有防腐层
    ……

每个项目都有自己的规范,但问题也常驻。如

2.1 缺乏显式、统一规范

规范是维系软件长期的演化。没有显式规范,项目维系只能依靠团队个人发挥,新人往往创造不同寻常新写法,项目朝着失控发展。某项目,多种不同的做法并存:

  • 数据库访问,有用MyBatis的,有用JDBC,也有Hibernate
  • 外部接口设计,有用REST风格的,有用URL表示各种动作
  • 文件组织,有的按照业务功能划分(比如,产品、订单等),有的按照代码结构划分(比如,Resource、Service等);
    ……

没有统一规范,每个项目上的新人都会骂街前人代码。然后,新人自己另起炉灶,又加了新东西。其实前任们的混乱一般也就是这么开始的。存在一个显式、统一的规范,项目就能按一个统一方向行进。即使后续设计要演化、规范要调整,统一规范也比散兵游勇代码更可控。

2.2 不符合软件设计原则

有次网关OOM。这个网关日常内存消耗达150G,一次流量暴增它就扛不住。后来经过优化,把内存消耗降到8G。单看数字,20倍优化,nb啊,具体咋整?
最核心内容就是构建防腐层,将请求过来的JSON转换成普通内存对象。而原来做法是把JSON解析器解析出来的对象到处用,因为这些对象上附加很多额外信息,导致占用大量内存。

只是因为旧的规范不符合软件设计原则而导致的错误:外部请求的对象需要在防腐层转换为内部对象。

2.3 防腐层

模型的一个规范:我接触防腐层的概念是从DDD的限界上下文开始。Eric用细胞膜的概念来解释“限界”的概念,细胞膜只让细胞需要的物质进入细胞,代码之间业务也存在这样一个界限,同一个对象的业务含义在不同的上下文中不一样。网上买书为例:

  • 购买页面,关注点在这本书的名称,作者,以及分类,库存等信息
  • 提交订单后,这本书就成为了订单上下文中的一个订单item,我们会关注这个item 的数量以及购买他的人是谁,以及书的配送地址等;
  • 订单提交给仓库后,仓库会关心这本书还有没有库存,以及打包状态,分拣,物流等状态

防腐层是在限界上下文之间映射(说白了就是交互)的方式,体现在代码上就是一个对象的转换,这个转换的意义在于隔离变化,防止因为对象在一个上下文中的变化扩散到其他的上下文中。

2.4 关于规范

规范也是团队文化中很重要的一部分,以持续集成为例子,它的执行严格依赖于团队的开发纪律文化,以为了所谓赶进度而单元测试覆盖很低或者直接不写;采用分支策略方开发,一星期都合并不了主干,类似的人到处倒是,也就因为这一点,很多团队都在持续集成这个环节上掉队了。所以开发规范真的很重要,时刻谨记:混乱始于没有规范。

3 模型与规范

二者相辅相成。一个项目最初建立起的模型,往往要符合一定规范,而规范的制定也有赖于模型。
就像讨论户型,可按照各种方式组合不同空间(模型),却不会把厨房与卫生间放在一起(规范)。

软件设计既包含构建出一套模型,也包括制定出相应的规范。

  • 特定技术、框架和中间件,只是支撑我们模型的实现
  • 设计模式、Controller、Service、Model这些东西也只是一个特定的实现结果,是某些特定场景下的模型

4 总结

软件设计应该包括:

  • 模型,是一个软件的骨架,是一个软件之所以是这个软件的核心。模型的粒度可大可小。我们所说的“高内聚、低耦合”指的就是对模型的要求,一个好的模型可以有效地隐藏细节,让开发者易于理解。模型是分层的,可以不断地叠加,基于一个基础的模型去构建上一层的模型,计算机世界就是这样一点点构建出来的。
  • 规范,就是限定了什么样的需求应该以怎样的方式去完成。它对于维系软件长期演化至关重要。关于规范,常见的两种问题是:一个项目缺乏显式的、统一的规范;规范不符合软件设计原则。

模型与规范,二者相辅相成,一个项目最初建立起的模型,往往是要符合一定规范的,而规范的制定也有赖于模型。

软件设计,应该包括模型和规范

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

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

相关文章

Java设计模式中状态模式介绍/状态模式怎么使用

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用! 6.6 状态模式 6.6.1定义 对有状态的对象,把复杂的"判断逻辑"提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变…

【C++】哈希表 | 闭散列 | 开散列 | unordered_map 和 unordered_set 的模拟实现

​🌠 作者:阿亮joy. 🎆专栏:《吃透西嘎嘎》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉unordere…

Ubuntu20.04/22.04 安装 Arduino IDE 2.x

这周收到两片基于LGT8F328P LQFP32的Arduino Mini EVB, 机器上没有 Arduino 环境需要新安装, 正好感受一下新出的 Arduino IDE 2.x, 记录一下 Ubuntu 20.04/22.04 下安装 Arduino IDE 2.x 的过程. 下载解压 下载 访问 Arduino 的官网下载 https://www.arduino.cc/en/softwar…

2021-04-12

今天在练习自定义标题栏(Android初级开发(四)——补充3)的过程中遇到了隐藏系统自带标题栏的问题,现将几种去掉系统自带标题栏的方式做一总结。大体上可以分为两种方式,一种是修改xml文件(这种方…

第六层:继承

文章目录前情回顾继承继承的作用继承的基本语法继承方式公共继承保护继承私有继承继承中的对象模型继承中的构造和析构顺序继承中同名成员访问非静态成员静态成员多继承语法注意多继承中的对象模型多继承父类成员名相同菱形继承概念菱形继承出现的问题虚继承步入第七层本章知识…

【数据分析】(task3)数据重构

note 数据的合并:df自带的join方法是横向合并,append方法是纵向(上下)合并拼接;pd的merge方法是横向合并,然后用刚才的apend进行纵向合并。数据的重构:stack函数的主要作用是将原来的列转成最内…

Redis基本类型和基本操作

2.Redis常见命令 Redis是典型的key-value数据库,key一般是字符串,而value包含很多不同的数据类型: Redis为了方便我们学习,将操作不同数据类型的命令也做了分组,在官网( https://redis.io/commands &…

阿里云轻量服务器下>安装宝塔面板>安装使用Tomcat服务器>通过公网ip地址>直接访问网站目录下文件

第一步 阿里云开放Tomcat 8080端口号 和宝塔面板 8888端口 第二步 如果你的应用镜像 一开始在阿里云购买服务器时候没有选择宝塔应用镜像 先打开如下界面 将系统中应用镜像 确定更换为 宝塔面板镜像 第三步 请在应用详情中 走完紫色所框选的步骤 第四步 将上一步获取到的…

cadence SPB17.4 - allegro - align component by pin

文章目录cadence SPB17.4 - allegro - align component by pin概述笔记实验备注补充 - 2023_0120_2337ENDcadence SPB17.4 - allegro - align component by pin 概述 allegro自带的元件对齐, 默认是对齐元件中心的, 对齐后的效果是中心对齐. 但是为了走线能走的最短, 拉线方便…

2023年春节祝福第二弹——送你一只守护兔(下),CSS3 动画相关属性图例实例大全(82种),守护兔源代码免费下载

2023年春节祝福第二弹——送你一只守护兔(下) CSS3 动画相关属性图例实例大全(82种)、守护兔源代码免费下载 本文目录: 五、CSS3 动画相关属性实例大全 (1)、CSS3的动画基本属性 (2&#xf…

TCP/IP OSI七层模型

作者简介:一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​​ 目录 前言 一.OSI七层模型 1.什么是OSI七层参考模型 2.七层每层分别的作用…

Spring热部署设置

手动热部署 热部署是指在不停止应用程序的情况下更新应用程序的功能。这样可以避免短暂的服务中断&#xff0c;并且可以更快地部署新的功能和修复问题。热部署通常适用于Web应用程序和服务器端应用程序。 在pom.xml中添加依赖&#xff1a; <dependency><groupId>…

cmake 02 hello_cmake

cmake 学习笔记 一个最小化的 cmake 项目 目录结构 F:\2023\code\cmake\hello_cmake>tree /f 卷 dox 的文件夹 PATH 列表 卷序列号为 34D2-6BE8 F:. │ CMakeLists.txt │ main.cpp │ └─.vscodelaunch.jsontasks.jsonF:\2023\code\cmake\hello_cmake>源码 main.c…

Java 集合 笔记

体系 Collection接口 List接口&#xff1a;按照顺序插入数据&#xff0c;可重复 ArrayList实现类&#xff1a;LinkedList实现类&#xff1a; Set接口&#xff1a;不可重复的集合 HashSet实现类 Queue接口&#xff1a;队列 LinkedList实现类ArrayBlockingQueue实现类PriorityQu…

Python CalmAn工具包安装及环境配置过程【Windows】

文章目录CalmAn简介安装要求我的设备1>CalmAn压缩包解压2>conda创建虚拟环境3>requirements依赖包配置&#xff08;包括tensorflow&#xff09;4>caiman安装(mamba install)5>caimanmanager.py install6>PyCharm添加解释器7>Demo演示8>遇到的问题CalmA…

DB SQL 转 ES DSL(支持多种数据库常用查询、统计、平均值、最大值、最小值、求和语法)...

1. 简介 日常开发中需要查询Elasticsearch中的数据时&#xff0c;一般会采用RestHighLevelClient高级客户端封装的API。项目中一般采用一种或多种关系型数据库(如&#xff1a;Mysql、PostgreSQL、Oracle等) NoSQL(如&#xff1a;Elasticsearch)存储方案&#xff1b;不同关系数…

【SAP Abap】X档案:SAP ABAP 中 AMDP 简介及实现方法

SAP ABAP 中 AMDP 简介及实现方法0、前言1、AMDP 简介1.1 代码下沉&#xff08;Code Pushdown&#xff09;1.2 AMDP 是托管数据库过程的容器1.3 AMDP 的优缺点1.4 几种数据库访问方式的区别1.5 几种数据库访问方式的选用1.6 使用的开发工具2、实现方法2.1 AMDP PROCEDURE&#…

Linux自带10种常用性能分析与监控工具

liunx的性能分析与监控这些问题是一个很重要的问题&#xff0c;我们需要解决这个问题就可以借助liunx中的一些工具来帮我们处理掉这个问题&#xff0c;以下将会讲一下目前liunx中常用自带的性能分析与监控工具 Linux自带10种常用性能分析与监控工具1.vmstat2.iostat3.iotop监控…

uniapp cli的使用

uniapp官方文档有很多地方写的不是很明白。写笔记还是非常有必要的。 cli入门 uniapp的cli分为两种&#xff1a;uni cli和hbuilder cli。下面是官方对于两者的定义。官方实际上是更推荐uni cli的。因为官方文档通篇都是介绍uni cli&#xff0c;也是优先介绍uni cli的。hbuild…

Linux系统之Bonding 网卡绑定配置方法

Linux系统之Bonding 网卡绑定配置方法一、检查本地系统环境1.检查系统版本2.查看服务器网卡二、创建网卡配置文件1.进入网卡配置文件目录2.拷贝eth0的网卡配置文件3.修改bond0网卡配置文件4.修改eth1网卡配置文件5.修改eth2网卡配置文件三、创建bonding的配置文件1.编辑bonding…