苍穹之边,浩瀚之挚,眰恦之美; 悟心悟性,善始善终,惟善惟道! —— 朝槿·《朝槿兮年说》

云原生时代架构设计(云原生时代程序员思维)(1)

众所周知,“软件架构(Software Architecture)”是软件设计的高层部分,是为了支撑更细节的设计的框架范畴的内容。一般软件架构主要是“系统架构(System Architecture)" 和“高层设计(High-Level Design)等,又或者称为“顶层设计(Top-Level Design)"。由此可见,我们常说“架构”主要指适用于整个系统范围的设计约束,而“设计”主要是指适用子系统层次或者多个类上的层次的设计约束。同时不难看出,软件设计是单纯的思维创造活动,其中最关键的就是抽象思维。

关于“软件设计(Software Design )"的定义:

软件设计是从软件需求规格说明书出发,根据需求分析阶段确定的功能设计软件系统的整体结构、划分功能模块、确定每个模块的实现算法以及编写具体的代码,形成软件的具体设计方案。软件设计是把许多事物和问题抽象起来,并且抽象它们不同的层次和角度。将问题或事物分解并模块化使得解决问题变得容易,分解的越细模块数量也就越多,它的副作用就是使得设计者考虑更多的模块之间耦合度的情况。

可以说,抽象是软件设计的核心,特别是在面向对象设计中,如果没有好的抽象概念。就不可能设计和编写出好的面向对象(Object Oriented,OO)程序。

云原生时代架构设计(云原生时代程序员思维)(2)

作为当今最重要的软件工程技术之一。面向对象(Object Oriented,OO)技术,实际上由“面向对象分析(Object Oriented Analysis,OOA)" , “面向对象设计(Object Oriented Design,OOD)“ 和 ”面向对象编程(Object Oriented Programming,OOP)"等3个部分组成。特别是在从事Java开发的小伙伴,对此的认知和理解应该是深有此感。在“云原生时代“Java依然以此作为业界标准。虽然Java云原生生态繁荣发展,但面向对象(Object Oriented,OO)原则依然没有改变。当然这本身就是Java语言提供的抽象机制,很多编程语言都提供这样的机制。可见抽象思维,对于软件开发者来说,树立这样的意识,更有益于我们在自我提升和“走得更远“。

云原生时代架构设计(云原生时代程序员思维)(3)

接下来,我们详细来了解一下面向对象(Object Oriented,OO)原则,其中:

首先, “面向对象分析(Object Oriented Analysis,OOA)",客观意义上来说是一种分析方法。主要是从问题领域的词汇表中找到类和对象来帮助我们分析需求和定义系统名词等。其核心主要是利用抽象思维聪复杂的需求中挖掘关键概念和对象实体等。

其次,“面向对象设计(Object Oriented Design,OOD)“,严格意义上来说是一种设计方法。主要是包括对象分解的过程和表示方法。其核心是设计系统的逻辑模型和物理模型,静态模型和动态模型等。

然后,”面向对象编程(Object Oriented Programming,OOP)",主观意义上说是一种实现方法。主要和我们选择的编程语言息息相关。在这种方法里,应用程序被组织成许多组相互协作的类,而这些类之间通过继承,组合,使用形成一定的层次结构。

综上所述,OOA最终的结果是帮助我们设计OOD的模型,而OOD的结果可以作为软件蓝图,最终利用OOP方法实现一个软件系统过程,便是我们常说的面向对象(Object Oriented,OO)的原则。由此可见,面向对象(Object Oriented,OO)基本都是对程序员的抽象能力要求更多,甚至更高。不管是OOA的问题领域分析,还是OOD和OOP的对象建模,以及编程实现都离不开抽象思维。

云原生时代架构设计(云原生时代程序员思维)(4)

在日常开发过程中,我们中的大多数程序员都是经过“高内聚低耦合“原则熏陶和滋养过的,但是查阅资料后发现,几乎都是在讲“单一职责原则“,“开闭原则“,“里氏代换原则“,“依赖倒转原则“,“接口隔离原则“,“迪米特法则“等六大设计原则,概念晦涩难懂,实际操作起来非常困难。因为在实际开发过程中来说,代码设计的过程是一个增量迭代的过程。坦白来说,我们并不能一次性就完成和完全准确地去定义和实现一个类和一个业务场景。对于最初的设计,依然需要花更多的时间去琢磨其中的基本内涵和概念边界。不论是代码重构还是重新设计,以及系统设计的可理解性和设计结构的完整性来说,其代价都是巨大的。但是我们需要一套度量指标来帮助我们在一开始的时候就尽量准确和符合业务需求设计。

云原生时代架构设计(云原生时代程序员思维)(5)

怎样才能知道我们在系统研发过程中,针对于某个类的抽象设计是否良好呢?一般情况下,我们主要从以下4个方面来度量或者说作为评判标准:

第一,耦合性。这个可以对标我们常说的“低耦合“,主要强耦合使得系统变得复杂。假如某个模块和其他模块过度相关,就会变得难以理解,变化和修正。通过降低耦合性,可以降低复杂性。就像在Java领域里面,耦合和继承之间存在矛盾,继承引入了严重的耦合。一方面,实际开发过程中,我们希望类之间"低耦合“;另外一个方面,我们又希望寄托继承能处理抽象的共性。就像我们常说的,“组合优于继承”,绝大一部分原因就是因为继承的耦合性过于强。所以,在了解Go语言的小伙伴都知道,Go语言在设计时候就直接去掉了继承。

第二,内聚性。这个主要对标我们常说的“高内聚“,主要强调测量某个模块内各个元素之间的联系程度。一般“高内聚”都是要求“功能性内聚“,即就是一个类和一个模块的各个元素一起工作,提供某种清晰界定的行为特征。

第三,充分性。主要是讲究类和模块之间记录某个抽象设计时有足够多的特征,从而这样的交互则变得有意义,否则即使封装成组件也用处不大,而且变得无用。这就表示着这是一个最小粒度的接口,而且有意义。

第四,完整性。主要讲究类和模块的接口记录某个抽象全部有意义的特征。可以说这个完全取决于程序员的主管臆测和经验判断,有可能会过度甚至过头。

由此可见可以看出,一个系统设计的层次性,几乎是棱角分明的。特别是在“微服务时代”,“DDD设计思想“软件分层模型,可谓是一剂”灵药“,但是不能说是”银弹“。

云原生时代架构设计(云原生时代程序员思维)(6)

“DDD设计思想“是指Domain-Driven Design领域驱动设计,面向领域模型,是综合软件系统分析和设计的面向对象建模方法。分层架构思想主要是“用户接口层(User Interface Layer)“,”应用服务层(Application Layer)“,”领域模型层(Domain Layer)“,”基础设施层(Infrastructure Layer)“等。还有我们常见通用分层领域模型设计有:

[1].DO->Data Object,与数据库表结构一一对应,通过Dao层向上传输数据对象

[2].DTO->Data Transfer Object,数据传输对象,通过Server Service 或者Manager Service 向外传输对象

[3].BO->Business Object,业务对象,由Service层输出的封装业务逻辑对象

[4].AO->Application Object,应用对象,由Web层与Service 层之间抽象复用业务对象模型

[5].VO->View Object,视图对象,通常是Web模板向渲染层传输对象

[9].Query->数据查询对象,各层接收上层的查询请求。超过2个参数的查询封装,禁止Map传输。

,