前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >软件设计到底是什么?

软件设计到底是什么?

作者头像
JavaEdge
发布于 2023-02-13 07:01:40
发布于 2023-02-13 07:01:40
4900
举报
文章被收录于专栏:JavaEdgeJavaEdge

软件设计是什么:

  • 就是讨论要用什么技术实现功能?
  • 就是要考虑选择哪些框架和中间件
  • 设计就是设计模式?
  • 设计就是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 总结

软件设计应该包括:

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023/01/21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
大家一直在谈的领域驱动设计(DDD),我们在互联网业务系统是这么实践的
前言 至少30年以前,一些软件设计人员就已经意识到领域建模和设计的重要性,并形成一种思潮,Eric Evans将其定义为领域驱动设计(Domain-Driven Design,简称DDD)。在互联网开发“小步快跑,迭代试错”的大环境下,DDD似乎是一种比较“古老而缓慢”的思想。 然而,由于互联网公司也逐渐深入实体经济,业务日益复杂,我们在开发中也越来越多地遇到传统行业软件开发中所面临的问题。本文就先来讲一下这些问题,然后再尝试在实践中用DDD的思想来解决这些问题。 问题 过度耦合 业务初期,我们的功能大都
美团技术团队
2018/03/13
2.5K0
大家一直在谈的领域驱动设计(DDD),我们在互联网业务系统是这么实践的
重新温习软件设计之路(1)
如果说学习数据结构和常用算法可以帮助我们写出较为高效的代码,那么学习软件设计相关知识则可以帮助我们写出较为高质量的代码,本文是我学习课程《软件设计之美》的学习总结的第一部分。
Edison Zhou
2021/01/07
6140
重新温习软件设计之路(1)
DDD在大众点评交易系统演进中的应用
本文主要涉及境外出行、商场团购和内容商业化等三类交易业务场景。在大众点评App里,在境外城市站有美食、购物、商场、景点、门票、当地玩乐等频道入口,可以购买境外出行交易产品,在境内的逛街/商场频道可以找到商场团购优惠以及商场团购代金券。
美团技术团队
2024/05/15
2460
DDD在大众点评交易系统演进中的应用
重新温习软件设计之路(5)
本文是我学习课程《软件设计之美》的学习总结第五部分,记录对于DDD领域驱动设计方法的整体理解。
Edison Zhou
2021/01/26
4940
重新温习软件设计之路(5)
十年开发老司机,感悟DDD领域驱动设计的战略设计到底是什么?
我们要解决的问题就是领域问题,相关概念如,子域、核心域、支撑域、通用域等。其实都是:如何分解问题。
JavaEdge
2021/12/07
6360
万字长文助你上手软件领域驱动设计 DDD
作者:faryrong,腾讯 CSIG 后台开发工程师 最近看了一本书《解构-领域驱动设计》,书中提出了领域驱动设计统一过程(DDDRUP),它指明了实践 DDD 的具体步骤,并很好地串联了各种概念、模式和思想。因此,我对书本内容做了梳理、简化,融入自己的理解,并结合之前阅读的书籍以及实践经验,最终形成这篇文章。希望可以帮助大伙理顺 DDD 的各种概念、模式和思想,降低上手 DDD 的门槛。 1.背景 领域驱动设计(DDD)由 Eric Evans 提出,并一经《领域驱动设计:软件核心复杂性应对之道》的发布
腾讯技术工程官方号
2022/03/29
2.1K0
领域驱动设计
本文对《领域驱动设计-软件复杂性应对之道》一书进行高度凝练,梳理了领域驱动设计的架构图、基本要素和重要概念。从细节入手,以小见大,你想知道的定义,这里都有。
kaiwest
2025/01/16
1180
探秘微信业务优化:DDD从入门到实践
引言 | 本文作者从微信团队维护的带货类项目所遇卡点出发,尝试用领域驱动设计方法(简称DDD),保障在快节奏、多人协作的项目迭代中,维持系统的可维护性、可拓展性、高内聚低耦合和稳定性。作者首先剖解相关概念原理,之后代入亲身参与的微信团队实际项目、围绕DDD方法进行优化实操。 DDD 全称 Domain-Driven Design,中文叫领域驱动设计,是一套应对复杂软件系统分析和设计的面向对象建模方法论。它由Eric Evans于2003年提出,但一开始不愠不火。直到MartinFowler于2014年发表论
腾讯云开发者
2022/12/09
1.1K0
探秘微信业务优化:DDD从入门到实践
《软件设计之美》阅读笔记
模型是一个软件的核心;模型的粒度可大可小;模型应该高内聚,低耦合;模型可以分层,底层模型提供接口来构建上层的模型。
chuckQu
2022/08/19
4660
详细聊聊什么是软件设计?
对软件做设计本质上就是对这个需求进行建模,软件需求是多变的,但其背后的模型机制相对稳定。
北洋
2023/12/10
2940
DDD 领域驱动设计落地实践系列:战略设计和战术设计
通过前面的文章介绍,相信大家对于什么是 DDD 有了初步的了解,知道它是一种微服务的架构设计方法论,为我们解决如何建立领域模型,如何实现微服务划分等提供了方向和指导。但是对于如何具体落地使用 DDD,可能大家还是一脸懵 B 的状态,因此从本文开始以及后面的文章将对如何进行 DDD 落地进行详细的阐述。在这其中还是会涉及到 DDD 中的一些重要概念,原本想着在一篇文章中介绍所有的概念,但是我觉得,概念总是在它该出现的时候出现才会让大家印象深刻,否则这些概念只是死板的概念,我们不清楚他为什么出现以及可以解决什么问题。
慕枫技术笔记
2023/03/20
9710
DDD 领域驱动设计落地实践系列:战略设计和战术设计
一文读懂DDD
DDD不是架构设计方法,不能把每个设计细节具象化,DDD是一套体系,决定了其开放性,体系中可以用任何一种方法来解决这些问题,但是如果一些关键问题没有具体方案落地,可能让团队无所适从。
春哥大魔王
2019/06/02
2.5K0
在重构业务系统时应用领域驱动设计
韩宇斌,现就职于罗辑思维得到后端,曾效力于好大夫在线、云智慧等。一线负责过传统软件公司ToB类和互联网公司ToC类的业务系统,理解体会过其中的相同与不同,擅长利用DDD和OO思想对业务需求进行分析建模与设计开发。
后端技术探索
2019/05/15
9010
在重构业务系统时应用领域驱动设计
DDD是如何解决复杂业务扩展问题?
业务初期,功能比较简单,CRUD基本可以满足。但随着系统的不断演化,业务系统越来越复杂,各模块间有着千丝万缕的关系,如何提升其扩展性,避免牵一发而动全身,是我们非常关心的。
微观技术
2020/08/20
1.9K0
DDD理论学习系列(13)-- 模块
1. 引言 Module,即模块,是指提供特定功能的相对独立的单元。提到模块,你肯定就会想到模块化设计思想,也就是功能的分解和组合。对于简单问题,可以直接构建单一模块的程序。而对于复杂问题,则可以先创建若干个较小的模块,然后将它们组装、链接在一起,从而构成复杂的软件系统。 在DDD中,模块的用途也是如此,通过分解领域模型为不同的模块,以降低领域模型的复杂性,提高领域模型的可读性。 2. DDD中的模块 模块是一个笼统的概念,比较宽泛,为了正确发挥模块的威力,理解模块的概念就十分重要。下面我们从具体的问题着手
圣杰
2018/01/11
1.1K0
DDD理论学习系列(13)-- 模块
数仓设计的几点原则
高内聚、低耦合是软件设计的常见概念,特别是在软件模块划分中会被常常提起,需要将功能相同的内聚在一起,将职责不同的功能解耦, 比喻说常见的MVC 分层模式,每一层负责单独的功能。高内聚、低耦合可以使得软件模块职责划分清晰,后期扩展性强,便于维护。
Flink实战剖析
2022/04/18
4380
对抗复杂度的圣杯战争:软件架构究竟该如何设计?
软件架构是计算机技术经典中的经典,在实际的生产环境中,我们往往面临着架构设计短板、接口老化、代码腐化等一系列问题,在飞速发展的业务需求下如履薄冰地艰难前行。好的架构一定是长出来的,但这背后往往更依赖于一个深度思考、高度可扩展的架构设计。本篇文章作者将为你详细拆解架构设计的道、法、术、器,助你一篇文入门架构设计的海洋!
腾讯云开发者
2023/12/23
7130
对抗复杂度的圣杯战争:软件架构究竟该如何设计?
领域驱动设计对依赖的控制
我在《解构领域驱动设计》一书中分析了软件复杂度的成因,一曰规模,一曰结构,还有一个则是变化的影响。规模与结构存在一定的矛盾关系:解决规模复杂度的有效方法为“分而治之”,一旦系统被分解为多个更为细小的软件元素,结构复杂度就会增加。结构与变化之间存在互相影响的关系:如果结构控制不合理,变化带来的影响就会更强,使得系统更加复杂。
张逸
2023/03/23
5010
领域驱动设计对依赖的控制
基于DDD的前端项目架构设计与实战
注意:本文极长,超过17000字,可能需要花30分钟以上才能阅读完,且内容要点密集,可能需要在读后花费比较多的精力和时间深入理解。
否子戈
2023/03/08
1.6K0
基于DDD的前端项目架构设计与实战
领域驱动设计——术语篇
随着微服务架构的普及,领域驱动设计(DDD)又重回软件设计战场。虽然团队内不少项目已经开始尝试,使用DDD指导项目的设计与开发,但还是有不少同学对DDD缺乏基础了解。因此,本文结合书本的定义及个人理解,对DDD中关键概念进行梳理,避免沟通时的歧义。毕竟DDD提倡使用通用语言,业务层面应该使用通用语言,技术层面也应该统一术语。
liliane
2022/07/27
8500
相关推荐
大家一直在谈的领域驱动设计(DDD),我们在互联网业务系统是这么实践的
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档