软件系统结构中都有哪些“关系户”

2021-11-12 18:27:20 浏览数 (1)

在一个软件开发环境里面会包含三种角色,分别是人、系统和机器。这里的人是指我们的程序员,系统就是程序员开发出的软件系统,然后把这个系统发布到机器上面并运行起来。

人开发系统,机器运行系统。

让我们想一想,在这个过程中,人会遇到什么问题,机器又会遇到什么问题,想清楚这两个问题之后,可能呢,我们就能够站在一个新的或者是比之前高的维度上来看待软件架构的问题了。

先看人会遇到什么问题。

业务逻辑复杂,不是那种简单的CRUD操作,程序员如果在这样的业务复杂环境下勉强把代码实现出来,如果没有充分考虑到业务代码的扩展性,那么日后的软件系统维护工作将非常痛苦,比如,来了一个需求,你会涉及到修改十几个类文件。

开发人员的要求是系统概念清晰,业务逻辑容易理解,可以直观地进行代码开发。

再看机器会遇到什么问题。

系统上线之后,用户的请求量非常的大,由于之前没有预估好,而且机器的性能也没有抗住这么大的量,想增加机器来扩容,结果却发现又很很困难。比如,每台服务器上面都是有状态的,我们还要保障新机器上面的请求会话要能够跟原来的机器上的会话保持同步。

机器的要求是系统能够水平扩展,支持软件容错,保证系统的高性能和高可用。

你会发现这三者之间,人和机器并不会直接发生关系,除非你拿斧子砍它,而是通过系统去把人和机器连接起来的。

这就是人和机器遇到的两类问题,我们这里也只是用这两类问题反映两个方向。

业务架构、应用架构、技术架构之间的关系

如何来解决上面说的人和机器遇到的问题呢。

我们这里来谈一下宏观上的思考方案。

你会发现,人和机器遇到的这两个问题,其实就是分别对应了业务和技术上的问题。

对于这两类问题,我们会通过业务架构、应用架构和技术架构上的思考方式来解决它们。

业务架构,定义了各个业务模块之间的业务关系,比如商品和订单的关系,一单多品;商品和库存的关系,库存增减,防止超买。

应用架构,定义了各个系统模块之间的通信关系,比如商品模块和订单模块需要进行通信,商品和库存之间需要通信。

技术架构,定义了各个系统模块之间的通信方式,比如商品和订单之间通过RPC,商品和库存之间通过MQ;同时还需考虑保障应用的稳定运行,保证业务不出问题。

业务架构、应用架构和技术架构,这三者之间存在一定的逻辑关系。先有业务,并且我们梳理出来的业务范围,明确好了包含多少个业务模块,当然,有时候我们还有个更时髦的词汇叫做领域,这里我们暂且用模块。

在确定好有多少个模块之后,就要清晰出哪些模块之间有关系,也就是上面我们提到的通信关系,最后我们还要确定出采用哪种方式来实现这些模块之间的通信,也就是我们说的通信方式。

这样梳理下来,就是业务关系-通信关系-通信方式,那么它们刚好也对应在了业务架构-应用架构-技术架构。当然我们的技术架构里面也不仅仅只是我们上面讲到的这些点,还涵盖了其它弹性能力,比如,采用了RPC的调用方式之后,还要保障系统要具备一定的RPC调用的容错能力。

系统是人的系统,架构首先是为人服务的。因此,业务概念清晰、应用分工合理、好理解是第一位的。然后,我们在考虑技术选型的问题,保证系统非功能性目标的实现。所以做架构设计时,一般是先考虑业务架构,再应用架构,最后技术架构。

架构、业务之间的关系

业务,具体一点就是我们的用户需求,架构,是实现业务需求的方法。

如果有一天,架构不再能帮助我们实现业务需求了,会发生什么?

代码逃逸出架构,把我们的系统搞的”支离破碎“,系统从有序变成了无序。

作为架构师的你可能闻到了一丝丝代码的臭味,甚或是那种危险的气息,但是,业务研发人员的研发里程碑截止时间就要到了,你可能会妥协,没办法。

你说,我要搞一个架构能提前预测未来所有的需求。当然,这样的志向肯定要受到鼓励和赞扬,但是,这很难。

未来到底有多远,所有到底有多大呢。

这个真的很难。

按照许式伟老师的建议,我们应该换一个角度来看待和解决这个问题。

在如何持续保证系统整洁有序的这件事情上,他给我们的建议是:连接性的代码越少越好

什么是连接性的代码?

就是把两个子的业务系统连接,构成一个大业务场景的代码。

我们的解决方案是减少或者杜绝这样的连接性代码。我们要做的就是。

如果有大业务场景,应该抽象出新的更大范畴的业务系统。

结果就是。

这样我们的焦点就始终在业务上。

系统模块、业务之间的关系

每个模块都是一个业务。

类、方法、接口、包、子类、子系统等等,都是我们所说的模块。

对,这些都是业务。

我们以往说的架构,从某个角度理解,它实际上也体现了需求的泛化,比如某一个正交设计的架构可以很从容地处理和适应各种需求变化。

从里面,拿出接口来单独说一下。

接口代表了要做什么,它有业务的输入和输出。

从程序的本质去思考,程序包含算法和数据结构。

类比一下,业务其实分为接口和业务数据,业务数据是业务的沉淀。

最后再说说模块之间的关系,这次,我们拿微服务来举例。

有两个独立的微服务系统A和B,如果A调用B的接口数量越多,说明这种静态依赖越大,如果A调用B的接口次数越多,说明这种动态依赖越大。

比框架(架构图)更重要的是数据结构,比数据结构更重要的是接口。

当我们谈到这里的时候,估计有的同学会想到两个词:扇入和扇出。

是有一定的相似度,扇入和扇出都属于上述的静态依赖关系。

在软件设计中,扇入和扇出的概念是指应用程序模块之间的层次调用情况。

扇入:是指直接调用该模块的上级模块的个数。

扇入大表示模块的复用程序高。

扇出:是指该模块直接调用的下级模块的个数;

扇出大表示模块的复杂度高,需要控制和协调过多的下级模块。

与爱学习爱思考爱记录的你共勉。

参考资料

《少谈点框架,多谈点业务》.许式伟

《架构的本质:如何打造一个有序的系统》.王庆友

0 人点赞