查看原文
其他

山哥新作:架构师必备技能之业务分析

The following article is from 技术方舟 Author 技术方舟

1


   

业务分析

业务分析是应用系统的思想和方法,把复杂的需求分解成简单的对象,找出这些对象的基本属性以及彼此之间的关系,系统分析也是系统开发中最重要、也是最困难的阶段,最终的架构设计也要依据业务分析的结果,运用合理的思想和方法,才能设计出满足逾期的系统架构,由此可见系统的分析和设计是程序员进阶中最重要的能力,是产品需求到编码实现过程中最重要的手段。

2


   

黄金圈法则

人人都知道自己是做什么的,有些人知道自己是怎么做的,但极少一部分人知道自己为什么这么做,这就是很著名的黄金圈法则,也叫作 2W1H 分析法。黄金圈法则源于知名广告人 Simon Sinek 的发现,是由“为什么(Why)、怎么做(How)、做什么(What)”三部分组成的由内到外的思维方式,如图所示。

黄金圈法则的三个层次与人脑的三个皮层精确对应,如图所示。人脑最外层为新皮质,负责理性思维分析和语言;中间层和最里层为边脑,负责情绪和行动,比如信任和忠诚,以及行为和决策。人们通过理智对外界信息和过往经历进行搜集与整理,传达给情绪,情绪影响直觉,直觉产生行动,而感觉则是直觉的直接反应,预示着如何行动。所以从外到内沟通时,通过说明“做什么”能够帮助我们理解大量的复杂信息,利用的是理性思维,它擅长分析,但不会促使人采取行动。但从内到外沟通时,是直接对应控制决策过程的。

如果将黄金圈法则对应工作的话,则:大部分人都知道做什么,能使用技术将工作做好,通常处于执行层;而有些人知道怎么做,具有组织、管理和协调能力,通常处于管理层;而只有极少一部分人知道为什么做,能够制定战略、目标和计划,具有宏观把控能力,通常处于决策层。企业中的执行层、管理层和决策层就形成了我们的人才金字塔,如图所示

所以,我们通过黄金圈法则能够解释为什么一些组织者或领导者能够在别人觉得不可能的地方激发出灵感和潜力,表现出卓越的天赋。那么,程序员如何从被动接收任务的执行层,发展成为具备系统分析和架构设计能力的决策层呢?有什么方法或捷径可循吗?答案之一是对 UML 建模工具的熟练运用,因为程序员除了需要具备写代码的能力,还需要具备凌驾于编程语言之上的能力,即系统分析与设计的能力,UML 就是用于系统分析和设计的一种工具。

3


   

业务分析和设计的方法

现在,用户的需求越来越复杂,变化也越来越快,如果仍然通过需求管理、需求跟踪等管理方式来约束和减少需求频繁变更对软件开发带来的冲击,则会导致软件开发变得僵硬,程序员更加疲惫。另外,用户的需求通常来自某个专业领域,比如法律、财务或电子商务等,每个特定的需求又有其特别复杂之处,所以几乎没有人能够第一时间抓住这些专业领域的需求本质。因此,用户的需求在历经几次演变之后变得面目全非,每一个加工制造环节都以为做“正确的事”。

在现实工作中,这样的局面一再上演,比如,产品经理在宣讲 PRD(Product Requirement Document,产品需求文档)时,需要将专业名词使用通俗的业务语言翻译给业务方,还要使用技术语言翻译给开发人员,这就很容易导致各方信息不对等,业务方的理解和技术人员的理解可能完全不一致。

因此,聪明的工程师们引入了灵活多变的面向对象分析与设计(OOAD)方法。面向对象分析与设计方法对复杂需求的解决方法是:委派专业建模专家跟踪理解需求,并在需求和需求之间搭建桥梁。

注意:面向对象分析与设计被拆分为系统分析和系统设计两部分,我们国家还专门有“系统分析师”和“系统设计师”两种职称考试。这样拆分的结果就是对需求分析的结果无法直接进行设计和编程,而能够运行的代码扭曲需求,导致客户在运行软件后才发现很多功能不是自己想要的,而且软件不能快速跟进需求的变化。

虽然面向对象分析与设计的思想带给分析和设计很大的灵活性,也对软件开发产生了前所未有的影响,但有一定的局限性:面向对象分析与设计主要关注微观层次的抽象,比如类和对象实例等;每个问题域通常都需要创建单独的用例分析模型,项目或产品的大方向在许多情况下变得很模糊,很难全局把控系统的总目标,所以这样的系统分析与设计方式存在很大的风险。

面向对象分析与设计的局限性,催生了面向服务分析与设计(SOAD)方法,它有效地弥补了面向对象分析与设计的局限性。同时,面向服务的架构(Service-Oriented Architecture,SOA)也走进了大众的视野并很快流行起来。

面向服务分析与设计并不是一种全新的分析与设计方式,只不过是从不同的抽象角度去设计一种业务模型。面向对象分析与设计可以说是一种自底向顶的设计方式,虽然面向对象的方法比起早期面向过程的方法有了很大的改进,但是放到复杂的商业逻辑里面,面向对象就显得远远不够,需要从更高的层次分解商业逻辑,所以才需要面向服务分析与设计。在做面向服务分析与设计时,首先会分离出业务流程和服务,再在这个基础上细化对象,这就是一种自顶向底的方法。面向对象分析与设计与面向服务分析与设计的抽象关系如图所示。

那么,面向服务分析与设计就是最好的了吗?它又有什么局限性呢?

众所周知,软件开发的流程通常为需求、分析、设计、开发、集成测试和交付部署。不管是在面向对象分析与设计中还是在面向服务分析与设计中,系统的分析和设计都是分开的、割裂的,即分析人员从领域中收集基本的业务概念,系统设计人员再将基本的业务概念映射为相应的编程工具的构造组件。在这个过程中,由于分析和设计的模型不同,导致在分析和设计之间形成一条鸿沟,如图所示。

2004 年,著名建模专家 Eric Evans 出版了其最具影响力的著名书籍 Domain Driven-Design architecture,其中提出的领域驱动设计(DDD)方法打破了分析和设计割裂的状态,并给出了领域模型的概念,抛弃了将分析与设计分开的做法,通过使用统一的模型来满足分析和设计的需求,使系统开发能够更加灵活、快速地响应需求的变化。

注意:DevOps 的出现又进一步填平了开发和部署之间的鸿沟,值得注意的是,任何新技术或概念的提出都不是凭空想象的,都是为了应对人们在生活和工作中遇到的瓶颈。架构师也需要具备发现系统中存在的瓶颈并给出相应解决方案的能力。

4


   

系统分析与设计的三个发展阶段

下面讲讲系统分析与设计的三个发展阶段。

4.1


   

面向数据的分析与设计

围绕数据库驱动的分析与设计可以说是系统分析与设计的第一阶段。软件设计总是从设计数据库及其字段开始的,这一阶段的特征就是围绕数据库编程,应用系统是典型的两层架构:分为界面层(User Interface)和数据库层(DataBase)。该阶段的典型技术为 Delphi 和 VB 等。

这种围绕数据库的分析与设计方法导致了过程化的编程思维,因为数据库结构由 DBA 设计后交由程序员编写大量的 SQL 语句实现,而 SQL 语句执行是有先后顺序的,所以程序员大多养成了面向过程的思维方式,长此以往成了习惯就难以改变。

面向过程(Proceduce Oriented)是一种思维方式,在面对一个问题时,我们通常先关注解决这个问题的步骤,即过程。比如对于如何将大象装入冰箱这个问题,我们想到的步骤是:第 1 步,打开冰箱;第 2 步,装入大象;第 3 步,关上冰箱。这就是典型的面向过程的思维方式,虽然这样更加直接、有效地可以完成问题,但是当面对更复杂的问题时,解决问题的过程会变得非常复杂和难以理解。同样,围绕数据库驱动的分析与设计有以下明显缺点。

不能迅速、有效、全面地认识反映和需求,在这种分析与设计思维中,世界不仅由简单的关系数据组成,还使用关系数据库反映现实需求,这不符合人类的自然思维,是一种扭曲的分析方法。

系统的性能很难提升,容易导致软件运行时负载集中在数据库端,使系统变成集中式和高风险的大型单体模式(Monolithic),丧失分布式集群处理能力。

面向对象编程语言和关系型数据库本身是矛盾的,因为关系型数据库分析与设计本身是面向过程的思维(这一矛盾在当今的实现中依然存在,不过在领域驱动设计中已有解决方案)。

4.2


   

面向对象和服务的分析与设计

随着系统的复杂度越来越高,面向过程的问题也越来越突显,因此诞生了具有划时代意义的面向对象分析和设计方法,应用系统也变成了经典的三层架构模式:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data access layer),如图所示。

此时出现独立进行分析和设计的两个阶段,系统分析和设计开始上升到一个相对更高的层次,拥有自己的一套科学且艺术的方法论,但也带来了一个致命的缺点,分析阶段和设计阶段不能很好地衔接,出现了难以逾越的鸿沟。因为分析人员负责从需求领域中收集基本概念,而设计人员负责指明一组能在项目中适应编程工具构造的组件,这些组件必须能够在目标环境中有效执行,并能够正确解决应用程序出现的问题。可以看到,分析与设计这两个阶段的目标并不一致,分析人员只关注需求分析,并不关心是否适合设计或者能否导出适合设计的分析结果;而设计人员因为要照顾程序代码实现的可行性,因此可能抱怨分析人员给出的结果过于粗糙,不适合设计,于是分析与设计两个阶段严重分裂,最终可能导致整个项目的失败。

另外,在分析和设计两个阶段虽然都使用了 UML,但是 UML 不是思想方法,只是一种分析与设计工具。假若将 UML 类比为 CAD 绘图软件,那么会 CAD 的绘图员就是建筑师吗?很显然不是。所以 UML 不是银弹,更不等价于分析与设计方法。

4.3


   

面向问题域的分析与设计

问题域模型有一个最流行的名字:领域模型,领域模型是一种概念模型,是对领域内的概念类或现实世界中对象的可视化表示。领域模型也成为概念模型、领域对象模型和分析对象模型。

Eric Evans 在 2004 年发表了 Domain-Driven Design –Tackling Complexity in the Heart of Software 的论文,主题便是领域驱动设计,还提出领域模型的分层架构,将整个系统划分为基础设施层(Infrastructure)、领域层(Domain)、应用层(Application)和用户接口层(User Interface),如图所示。

领域建模是一种艺术,融合了分析阶段和设计阶段,目的是使复杂的软件快速应付变化。Evans DDD 抛弃了分裂分析模型与设计的做法,使用单一模型满足这两方面的要求,该单一模型就是领域模型。领域模型同时满足分析原型和程序设计,如果一个模型在实现时不具备可行性,就需要重新寻找新的模型,如果该模型没有忠实表达领域的关键概念,则也必须重新寻找新的模型。所以,领域建模的过程把分析和设计阶段变成了单个的循环阶段,把分析和设计紧密联系起来,使领域建模专家不再只关注需求概念的收集,也关注程序代码的设计与实现。

5


   

面向对象的分析和设计

面向对象分析与设计是指根据面向对象方法学对软件系统进行分析与设计。

在面向对象分析与设计的定义中有三个关键词:面向对象、分析和设计。所以,为了更好地理解面向对象分析与设计的作用,我们首先要理解什么是面向对象,以及面向对象分析和面向对象设计的原则。

5.1


   

什么是面向对象

面向对象是对现实世界进行理解和抽象的方法,是计算机编程技术发展到一定阶段后产生的一种软件开发方法,具有抽象、封装、继承、多态等特征,还沉淀出设计原则和设计模式的智慧结晶。我们可以使用一张图来更为形象地展现面向对象所涉及内容之间的关系,如图所示。

5.2


   

面向对象的特征

封装:把对象的属性和方法结合成一个独立的整体,隐藏实现细节,并提供对外访问接口,被封装的对象通常被称为抽象数据类型。我们通常将变化的内容封装起来,就可以在不影响其他部分的情况下修改或扩展被封装的部分。封装变化是所有设计模式的基础,用于提供程序的可扩展性。

继承:从已知的某个类中派生出一个新的类,将这个新的类叫作已知的这个类的子类,已知的这个类就是这个新的类的父类。子类继承了父类的所有非私有化属性和方法,并能根据自己的实际需求扩展出新的行为。继承实现了代码的重用,因此也提供了系统的重用性和扩展性;但是继承破坏了封装性,因为它是对子类开放的,修改父类会导致所有子类的改变。因此继承在一定程度上破坏了系统的可扩展性,因此优先使用组合而不是继承是面向对象开发中的一个重要经验。

多态:同一操作作用于不同的对象,可以有不同的响应,产生不同的执行结果。接口的多种不同的实现方式通常被称为多态。接口是对行为的抽象,主要目的是为不相关的类提供通用的处理服务,比如鸟会飞,但是飞机也会飞,我们可以让鸟和飞机都实现飞这个接口,这样就实现了系统的可扩展性。

抽象:表示在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同但本质相同的具体概念的抽象。它其实就是一个过程,是一个提炼事物之间共同拥有的元素的过程,而这些事物之间共同拥有的元素往往是这一事物区别于其他事物的关键内容,这些元素就构成了事物的本质。所以,抽象作为面向对象的基础,也是面向对象的本质或者说是面向对象的核心。

5.3


   

面向对象设计的原则

为了设计出一个好的系统架构,就必须遵照一定的规则,而衡量软件设计质量的首要标准就是该设计能否满足软件的功能需求。除了功能需求,还有很多衡量软件设计质量的标准,主要包括高内聚、低耦合、可扩展和可复用。

高内聚:指每个模块尽可能独立完成自己的功能,不依赖模块外部的代码。一个软件模块由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。

低耦合:一个设计良好的系统,模块与模块之间应该尽可能独立存在,模块与模块之间的接口应该尽量少而简单,也就是说,让每个模块尽可能独立完成某个特定的子功能。模块与模块之间的联系越复杂,耦合度便越高,会导致牵一发而动全身。如果某两个模块间的关系比较复杂,则最好先考虑进一步的模块划分。

可扩展:用于应对更大规模的业务及软件的成长,通常采用动态加载的插件、回调函数、抽象接口及认真设计的代码结构和类层次结构,使系统在面对不断变化的需求时,其代码不被大量重构开发,比如添加新功能或修改完善现有功能。

可复用:又叫作重用,即重复使用,可以利用已有的代码或者相关模块去实现新的功能需求,从而得到较高的生产效率及随之而来的低成本和高质量。

之间的联系,最后用面向对象的语言实现这种客体及客体之间的联系,它们之间的关系如图所示。

回顾前面介绍的将大象放入冰箱的例子,我们如何使用面向对象思想实现这个例子呢?首先,找出现实世界中的动作和实体:1、打开冰箱;2、将大象放入冰箱;3、关闭冰箱。然后,抽象出概念:1、冰箱、可以打开门、可以存储、可以关门;2、大象、体重、体积。最后,用计算机中的类来实现该逻辑关系,这样就有了 elephant 和 fridge 两个类。

面向对象的代码实现如下所示:

虽然面向对象起初专指在程序设计中采用封装、继承、多态、抽象等设计方法,然而现在它已经渗透到软件开发的各个方面,比如面向对象的分析(OOA)、面向对象的设计(OOD)和面向对象的编程(OOP)等环节,其各环节的职责如下。

  1. 在需求分析阶段采用面向对象的分析方法,这个阶段不需要思考怎么用程序实现它,只需要思考和分析需求中稳定不变的客体都是些什么,这些客体之间的关系又是什么,以及完成概要建模。

  2. 在设计阶段采用面向对象的设计方式,把在第 1 步分析出来的需求通过进一步扩充模型,变成可实现的、符合成本的、模块化的、低耦合高内聚模型。

  3. 在编程开发阶段采用面向对象的编程语言来具体实现前一个阶段得到的业务模型。

6


   

小结

程序员的成长路线大体是在管理线和技术线上形成突破,当然也有结合起来相得益彰的。而技术上的追求,架构师则是一个重要的门槛,对于刚入行的程序员可能会认为架构师就是画架构图的,诚然架构师很重要的一个职责是绘制架构图,但这只是其中一个很小的环节而已。

实际上架构也只是系统设计里面的一个重要环节,除了架构还包含了商业诉求,业务建模,系统分析,系统设计等重要领域。下一篇会讲解如何从服务角度进行业务分析,敬请期待!



推荐阅读

微服务架构最强讲解,通俗易懂,写得太好了!

2021-06-21

标签类目体系的价值与意义

2021-06-18

程超:突破瓶颈!如何不断的提高自己

2021-06-17

资深架构师手把手教你性能优化

2021-06-07

李伟山:金融撮合架构

2021-05-31

阿里专家晨末:什么是技术一号位?

2021-07-08

资深架构专家聊架构之道:规划、简化和演化

2021-07-01

浅谈云原生架构的 7 个原则

2021-07-23

资深架构师十几年的架构干货经验总结分享!

2021-07-19



: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存