架构设计思考

要想跑得快,先要跑的稳。

Robert C·Martin 《整洁架构之道》

现状

一般来说,业务的发展会经历这么几个阶段:需求调研、需求设计、需求评审、软件设计、开发、上线、迭代/维护。

在大部分公司里,调研和需求设计是产品经理的事,一线开发人员往往只参与软件设计之后的事,虽然会有需求评审环节,但开发人员往往也只在产品设计的基础上提出一些意见,对大方向不会产生什么实质性的影响,基本上业务的成败跟开发人员没有太大关系(除非体验做的很烂用户不愿意用)。

又由于很多需求是倒排期,开发时间紧,开发人员往往匆匆完成软件设计,甚至不怎么进行设计,就直接投入到开发过程中。


问题

在整个业务生命周期中,至少有以下几个问题:

  1. 开发人员对业务需求设计阶段参与过少,基本只是个接活干活的
  2. 由于工期或者习惯问题,软件设计阶段时间太短,甚至没有设计
  3. 开发阶段占大头,部分未经过良好设计的代码直接上线

归结起来其实主要是两个问题:

  1. 开发人员在需求设计中参与过少
  2. 设计和开发的权重有问题

接下来对这几个问题进行单独分析


问题分析

问题一. 开发人员在需求设计阶段参与过少

这会导致什么问题呢?我认为至少会导致以下几个问题:

  • 开发人员对需求的理解有偏差,导致错误的实现,在验收阶段不断返工重做
  • 将系统流程完全实现成了业务流程,随着后续产品需求不断修改,实现也要不断推倒重做

前期的低参与、低投入,导致了后期的高成本。

我的观点是,在需求设计阶段,产品经理有义务证明自己需求的合理性,软件开发人员也有义务参与到需求设计中

《领域驱动设计》和《实现领域驱动设计》这两本书中,都强调了开发人员和领域专家之间良性互动的重要性,书中认为,领域专家和开发人员需要提炼出一种「通用语言」,提高沟通效率,让所有人都参与其中。不过据我观察,开发人员可能对和产品经理打交道这件事会比较排斥,认为开发工作已经很忙,不想再掺和到需求的讨价还价中。即使想实践 DDD,也只愿意使用战略和战术设计,只能算是 DDD Lite。

软件架构设计的目的在于「管理业务复杂度」,如何管理业务复杂度?

寻找变化背后的不变性

寻找业务变化背后的不变性,并将不变的部分和变化的部分做分离,提高不变部分的复用性。这也是我认为的领域建模的目的。从这个角度来说,我认为不够复杂多变的业务也没有必要使用 DDD。

典型的 DDD 架构(松散的分层架构)
ddd-layers

领域层位于业务层下方,业务层面向具体的业务场景,领域层抽象出较为稳定的领域服务,从架构设计原则上来看,也符合「越往上越接近用户,越多变;越往下越远离用户,越固化」,而且这种设计方式,很容易将领域层孵化成为平台服务,领域层不面向单一业务场景,而是面向通用领域,自然可以服务多个业务。

如果开发人员只接活做而不参与到需求阶段,那寻找「变化背后的不变性」就无从谈起

问题二. 软件设计和开发的权重

要想跑得快,先要跑的稳,我认为多花点时间在设计上会取得更长远的收益

开发只在整个软件生命周期中占据一小部分,更多的时间是在迭代和维护,软件架构在这个时候体现的作用会越来越大。如何衡量一个软件架构设计的好坏?在《整洁架构之道》中,作者认为,软件架构的优劣可以用它「满足用户需求所需要的成本来衡量」。优秀的架构成本很低,并且在系统的整个生命周期内一直都能维持这样的低成本。这个成本自然包括人力成本。

当你发现增加一个简单需求时竟然需要修改好几个模块,这就说明架构设计出现了问题。

既然架构设计这么重要,那如何做好架构设计?《软件架构设计》和《整洁架构之道》等书中都提出了一些通用的手法和套路。

一些简单原则

一个比较的方法是从用户角度切入,分析这个系统面向哪些用户,他们的行为是什么,根据这些用户行为设计用例,并将用例进行划分,如何划分用例,这里有一些比较通用的原则:

  • 类或者组件层面以下 SOLID
  • 组件之间 组件耦合原则、组件聚合原则

架构设计还是要多总结多实践,融汇贯通。