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

软件设计到底是什么?

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

软件设计是什么:

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 核心模型
  • 2 约束的规范
    • 2.1 缺乏显式、统一规范
      • 2.2 不符合软件设计原则
        • 2.3 防腐层
          • 2.4 关于规范
          • 3 模型与规范
          • 4 总结
          相关产品与服务
          持续集成
          CODING 持续集成(CODING Continuous Integration,CODING-CI)全面兼容 Jenkins 的持续集成服务,支持 Java、Python、NodeJS 等所有主流语言,并且支持 Docker 镜像的构建。图形化编排,高配集群多 Job 并行构建全面提速您的构建任务。支持主流的 Git 代码仓库,包括 CODING 代码托管、GitHub、GitLab 等。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档