浅析软件架构

2023-05-16

一、软件架构的定义

    用简单的定义来说,架构就是对系统中的实体以及实体之间的关系所进行的抽象描述。在由人类所构建的系统中,架构可以表述为一系列的决策。

    纯软件系统的架构可以理解为是对现实世界或期望中的运行模式或模型的抽象描述,以便实现一套符合干系人预期的软件系统。

二、软件架构解决什么问题?

    软件系统的创建是一个从无到有的过程,其组成实体、实体间的关系又相对复杂,不可见且不可控,现实世界中的运行模式对软件系统有一定的参考意义又不完全对应。因此在系统设计的初期对其架构进行恰当的描述并与用户或干系人进行充分的讨论、沟通就非常必要。而架构描述文件的生成、迭代是项目前期工作的主要成果。

    从这一点来讲,软件架构设计实现了对软件系统的初步定义,固化了软件系统的基本形式与功能,确定了开发的成果和产品,特别是在一些可视化设计工具的辅助下使软件系统架构设计实现了一定的可视化。架构设计的产品是项目讨论、推进的主要媒介,对项目的后续推进、开发具有指导性的意义。 

三、用系统性思维确定架构

1、确定系统及其形式与功能

        系统同时具备形式与功能这两个特征。形式说的是系统是什么,而功能则说明系统能做什么。每个由人类所构建的系统,都需要用某种形式的工具来承载功能,也都具备某一套过程,以及某个与价值有关的操作数,系统存在的意义就体现在这个操作数的变化上。也就是说,每个系统都以某种形式作为工具(该形式描述了这个系统是什么),也都能执行某种功能(该功能描述了这个系统能够做什么),而功能又是由过程(也就是系统所要完成的转换操作)与操作数(系统所要转换的对象)组成的。因此,我们可以说:每种系统都具备形式、过程与操作数这三项特征。

        艾弗拉姆·诺姆·乔姆斯基(Avram Noam Chomsky)在《句法结构》中提出转换文法时,曾经给过一个观点,认为人类所有的自然语言都具备一种深层结构,而这种深层结构也包括三个部分:第一部分是一个名词,充当执行动作所用的工具(我们称之为形式);第二部分是一个动词,用来描述该动作(我们称之为过程);第三部分是一个名词,用来代表动作的对象(我们称之为操作数)。不论哪一种人类语言,其基本单位都是句子,句子中含有两个名词(一个是工具,另一个是操作数)以及一个动词。因此,这种“名词-动词-名词”格式的模型,或者说“工具-过程-操作数”格式模型,要么是所有系统均具备的基本模型,要么就是人脑在理解任何一种系统时都要采用的思维方式。这可能是人类思维的通用模式。

        总之:

  • 所有系统都具备形式(用来描述该系统是什么)和功能(用来描述该系统能够做什么)。形式是执行功能所需的工具。
  • 功能可以进一步拆分为过程(也就是所要执行的转换行为)及操作数(也就是将要转换的那个对象或其状态将要改变的那个对象)。
  • 在人类所构建的系统中,绝大多数系统的主要功能都比较清晰。
  • 对于演化而成的系统来说,其主要功能比人造系统更加难以识别,而且不同的解读方式通常会得出不同的结论。
  • 系统三特征(作为工具的形式-过程-操作数)与自然语言的深层结构(名词-动词-名词)非常相似。

        

2、确定系统中的实体及其形式与功能

                一般来说,通过以下几个步骤来确定系统中的实体及其形式与功能。

  1. 确定如何将系统初步分解为恰当的实体。
  2. 用整体思维找出潜在的实体。
  3. 通过对重点的分析,把注意力集中到重要的实体上。
  4. 为实体创建抽象
  5. 定义系统的边界,并将其与外界环境隔开。

3、确定实体之间的关系

        系统中实体间的关系按特征可分为两类:功能关系和形式关系。

        功能关系,是指用来完成某件事情的实体间所具备的关系,此关系可能涉及实体之间对某物的操作、传输或交换。为了强调其动态性,我们有时也把功能关系称为交互(互动)关系。

        形式关系,是某段时间内稳定存在或有可能稳定存在的实体间所具备的关系。形式关系通常体现为连接关系或几何关系。为了强调其静态性,有时也把形式关系称为结构关系。

        一般来说,功能关系通常需要以形式关系为前提。形式关系是功能关系的载体。形式关系通常更为具体一些,因此我们在思考关系时,可以从这种关系入手。在检视第一条形式关系时,也应该试着思考它所承载的功能关系。形式关系的重要性,主要体现在它对功能关系的承载上。由于涌现物出现在功能领域里,因此功能交互才是真正重要的关系。

        形式关系与功能关系可以跨越系统边界,它们可以发生在系统内部的实体与系统外围环境中的实体之间。这叫做系统的外部接口。

        在系统的定义中,就是实体之间必须要具备关系,这些关系可以是形式上的(用来表示相关的实体已然存在或有可能 存在,这种关系又叫结构关系),也可以是功能上的(用来表示相关的实体会对某物执行操作,这种关系又叫做交互关系)。

4、确定系统涌现的功能

        系统的奇妙之处,在于涌现。系统定义的后半句就是为强调涌现而说的。“更大的功能”是通过涌现而产生的。

        系统的形式领域并不会发生“涌现”,仅体现为简单的连接。而在功能领域,不同实体的功能交互,任何事情都可能发生。系统的强大,正是体现在涌现物的这一属性上。

        系统思维的主要目标,就是努力了解并预测涌现物以及涌现物带给系统的强大能力。

        预测涌现物有三种方法:

  • 根据以前做过的情况来预测,也就是根据先例预测。
  • 做试验。
  • 建模

        如果系统即没有先例,又不能试验,而且无法可靠的建模,那该怎样预测其涌现物呢?在这种情况下,我们必须对将要涌现出来的功能进行推理。在推理过程中,尽管我们可以从先例中得知一部分信息(这部分信息是通过对相似但不相同的系统进行观察而得到的),同时还可以通过试验 和不完备的建模了解一些情况,但对涌现物的最终推定,还是必须依靠我们自己的判断力。

        涌现物的属性既给系统带来了强大的力量,又为系统思考者对其进行的理解与预测工作带来了挑战。

四、复杂系统的架构

        系统之所以变复杂,是因为我们对系统总是“要求太多”:要求系统有更多的功能、更好的性能、更加健壮、更加灵活。变复杂的另一个原因,在于我们要求本系统能够与其他系统相互协作、连接。

        复杂度指标可以描述系统的复杂程度。还有一个概念叫难懂(complicated),指某物是否难懂,其复杂度是否超越了人类有限的观察和理解力。

        架构师的工作是训练自己的思维,用它支理解复杂的系统,令那些系统不再那么难懂。我们应该努力构建易懂的架构,使得该系统上工作的其他人员(例如设计者、构建者、操作者等)可以较为容易地理解这个系统。

        设计一套良好的系统架构,实际上可以归结为:构建一套具备必要的复杂度同时又不难懂的系统。

1、系统的分解

        1.1、分解

        分解就是把实体分成小的部件或组成部分。在应对复杂度的诸多工具中,“分而治之”是一项基本策略,它把大问题持续分解成小问题,直到每一个小问题都能够解决为止。

        把系统分解成部件的难点并不在于分解,而是体现在用分解出来的实体构建整个系统的这一过程上。这个过程通常称为整合(integration)。对于形式领域来说,整合就是把各部件所具备的形式聚合起来,在这一过程中,我们会担心这些元素在物理上或逻辑上是否能够合适地拼接在一起。对于功能领域来说,我们会把大功能分解成一些小的功能,然后把每个实体所具备的功能重新组合起来,在这一过程中,我们会遇到涌现物,这是真正的挑战所在。

        1.2、体系

        体系(hierarchy)是另一种理解并思考系统复杂度的强大方法。体系就是一种树形的层级结构,其实体均处在某个层次或某个位阶,这些层次是按照上下顺序排列起来的。社会系统中经常看到各种体系。比如:政府、军队、公司等组织结构。

        需要注意的是,体系并非总是能够明确地展示我们相要的信息,有时还需要做层级分解。

        1.3、层级分解

        将分解与体系这两种手段结合起来,通常可以实现多层次的分解或层级化的分解,即大于两层的分解方式。

        1.4、简单、复杂度适中、以及复杂的系统

        按照一套特定的分类标准,系统可以分为简单、复杂度适中以及复杂度较大三种。若只需一次分解即可将其完整地描述出来,那么它就是简单的系统。若两次分解后,可以描述出系统,且每个上级部件所统领的下级部件都不超过7个(该上限可以左右浮动两个,这要示最底层的实体数量不超过81个),那么这种系统就是复杂度适中的系统。超出了复杂度适中的系统,就是复杂度较大的系统。

        1.5、原子部件

       上小节对系统分类时,某种程度上要依赖于“原子部件”。一般意义上说,不能拆解的东西都可以叫做原子部件。在信息系统中也可以把握一条简单的规则:凡是一经拆解就失去意义的东西,都可以称为原子部件。

2、特殊的逻辑关系

2.1 类/实例关系

        理解并管理复杂度的另一项工具,是类/实例关系。这种说法更多用在软件中而非硬件中。类(class)是一种结构,它用来描述某种事件所共有的特征。而实例(instance)则是类的具体表现。实例也称为类的实例化。

        如果某种实体反复的出现,或是某个类能够轻松的加以实例化,那我们就可以考虑用类/实例关系来有效地管理复杂度。

2.2 特化关系

        特化/泛化关系,描述了通用的物体与一组特殊的物体之间的关系。特化这一概念类似于面向对象编程语言中的继承。我们可以从某个通用的类中创建一个子类,使得该子类继承通用类中的某些属性及功能并且能够添加新的属性及功能。

2.3 递归

        若某套过程或某个对象把它自己包括进来,那么就发生递归(recursion)。即递归就是一种与自身相似的方式来使用实体或关系的现象。类似面向对象设计模式中的自包含模式,如:文件夹、菜单等都是这种模式。

3、对复杂系统进行思索

3.1 学会向不同的方向探索系统

        从上到下和从底到上是思考系统时的两种方向。大部分情况下,我们更习惯自顶向下、由大及小的思考过程。逆向则是自底向上,也就是先思考工件、能力或服务等最底层的实体,然后沿着这些实体向上构建,以预测系统的涌现物。另外,同时从顶部和底部向中间行进,叫由外向内(outer-in)的思考方式。从中间一点向上下两边进行探索叫(middle-out)。

        真正复杂的系统实际上是没有顶和底的,因此,我们在实际工作中的方式更像由内及外(middle-out)的办法,也就是在系统层级中选定一个点,然后试着由该点开始向上或向下探索1~2层。好的架构师应该能够熟练运用所有这四种方法。

3.2 交替思考

        Zigzagging(交替思考、Z字形思考)是Nam Suh在研究公理化设计时提出的一个术语。Suh发现,我们在思考系统时,思维会在形式领域和功能领域之间来回切换,也就是先在其中某个领域尽可能久地进行思考,然后再换到另一个领域。在思考系统的不同层面时,我们依然可以运用这种在形式与功能之间反复跳跃的思维模式。

五、简单实践

          一些可视化的架构设计和建模工具,在架构设计和后续开发间进行了一定的关联,可以大大提高工作效率。如Visual Studio中的UML设计和建模工具,将实体和类进行了关联,可以由架构设计直接进入编码阶段。其他的常用架构展示工具有SysML、OPM等。SysML使用UML的一个子集,并添加了一些有助于对系统要求及系统效能进行建模的新特性。


1、顶层图(系统形式和功能)


2、实体及其之间的关系

 

 3、实体(类)图及代码(创建实体的抽象及预测涌现物)

参考资料

《系统架构》(美)爱德华·克劳利(Edward Crawley) 布鲁斯·卡梅隆(Bruce Cameron) 丹尼尔·塞尔瓦(Danial Selva)  著   爱飞翔 译

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浅析软件架构 的相关文章

随机推荐