软件结构的十个基本概念

概念的意义

概念的初衷,是为了沟通,为了加速理解。

如今的这个社会,概念的定义,一部分变成了「市场宣传」的「洗脑行为」。 比如,各大汽车厂商,都会定期面向市场发布「概念车」,向广大的消费者宣传品牌理念,技术趋势,营造诸如「高科技」、「人性化」、「环保节能」的品牌形象。

人的差异,是源于天生对于概念的不同认识、理解,这和其经历过的环境,接受的教育,传承的文化息息相关。不同文化和理念,会对相同概念产生不同的诠释,并体现在对相关事物进行选择的各个方面。

概念的定义

一个好的概念,一定是面向目标受众,指代清晰,便于理解的。

非普适的、专业领域的概念,有另外的称呼——术语。

越抽象的概念,其内涵越小,外延越大,也就是可以解释的范围越大,可以根据实际情况解释出不同的内涵。

越具象的概念,其内涵越大,外延越小,也就是没有太多解释的必要,有特指的效果。

聚合概念

一般的概念定义,是基于一些已经存在、被广泛接受的概念,进行缩略和重组,赋予新的内含,这种类型概念在理解时,一般可以通过「望文生义」的想象,由受众自行解释内涵。

以「手机」这个概念,举个例子。

  • 手机 —— 可以拿在手里的电话机(当然,手机在别处也成为「行动电话」)
  • = 手持 + 电话机
  • = 手持 + (用电 +可以通话 + 机器)

可是,「无绳电话」又是另外一个截然不同的解释了。概念的诞生,有时会带着时代的烙印。

借用概念

当事物的内涵发生质变的清下,外形不变,人们就又会对概念进行升级。有时,会借用一些概念,以示区分。

以「功能手机」和「智能手机」这两个概念,再举个例子。

  • 功能手机 —— 拥有不同外壳,但仅仅可以拨打电话,发送短信的手机
  • 智能手机 —— 可以连接数据网络,自行安装App应用,满足每个人个性化需求的手机

「智能手机」其实是借用了「智能」这个概念,其实远远没有达到「智能」,任何手机目前都没有「先于人类思考、归纳、演绎」的能力,事实上是由无数的程序员,通过代码,以软件的形式,把预设好的场景、规则植入了硬件之上,使之产生了「智能」的假象。

人们同样喜欢在从其他完全不相关的行业、生活场景中,借用概念。

同样的,在英文中,人们习惯于对词根进行重组,将单词进行拼接。

所以,借用概念,有时也是偷换概念。

创造概念

创造一个全新的概念,是需要大量的文字、图片、语音、视屏,多维度进行阐释。更多的情况下,全新的概念,太过于抽象,而被定义成了品牌。

全新的概念,其实没有那么容易被创造。

概念的根源,是宗教和信仰,是看上去不证自明的公理。(科学,也是一种宗教)

概念的演变

大部分的概念,是通过组合或者借用的方式形成的。

当这些被重组的概念的内涵,作为顶层概念的根基,随着社会发展产生变化的时候,会逐渐与定义时偏差的解释,这导致了顶层的概念同样需要进行重新的定义和解释。

十个基本概念

软件只有被运行,才能产生使用价值。它始于硬件,终于用户交互,是具备「层叠集成」特性的产物。

代码

代码,可以用来表示与计算机无关的实体、关系、逻辑,也可以用来协调和控制计算机的运行时逻辑。

代码,简单而言,至少应该被分为源代码和机器码。

源代码和机器码,是代码的两种形态,前者用于和人的交互,后者用于和机器的交互。两者的相互转换的方法,是编译和反编译,当然这两个过程会产生失真,反编译比较严重。

版本

代码是对客体,用特定的计算机语言进行的「结构化描述」,也是阶段性认知的产物。

版本,则是对代码进行了「不可变的固化」,形成一个暂时地「附属代号」。

版本的意义在于,容易让受众理解,一个新的版本是进行了部分优化、正向修正的结果,但代码主体没有发生太大的变化。

数据

数据,是特定的计算机处理逻辑能够处理的「结构化信息」。它可以存在于内存或者处理器中,也可以存在于存储介质上,还可以存在于网络中。

数据,是代码的血液,使运行中的代码产生实际价值。

资源

资源,是个广义的、相对的概念。

正因为软件在运行时,是具备层叠集成的特性,所以不管采用哪种分层方法,都能为某一层的软件,找到它的运行时依赖——资源。

资源,既包括用代码描述的可被处理的数据,也包括通过代码定义的逻辑处理能力。

环境

环境,也是一个广义的、相对的概念。

软件需要被运行,环境是软件的物理运行时基础。不同层面的软件,具有不同的运行环境。

例如,操作系统的运行环境则是硬件,而浏览器中的脚本代码,运行时环境则是脚本解释器。

容器

容器,同样是个广义的、相对的概念。

容器,是对运行时环境的进一步虚拟划分的结果。 隔离受控是容器的特性 ,两个不同容器中的代码,其对资源的操作是严格受到容器控制的。

  • 提供组件(即容器中的内容)的运行环境。
  • 一种容器,面向不同内容,是同质的。
  • 容器保证运行期不同内容的隔离。

不同层面的软件,可以有不同的实现。例如,在操作系统层面的虚拟化(Docker)、服务与应用层面的运行时环境(OSGi Bundle)等等。

组件

组件,是一组能够独立部署于容器内,提供有效功能的代码,是模块的物理集合。组件在设计时,可以申明运行时的资源依赖,并由容器在运行时为期加载所申明的资源。

一个容器内可以有 m 个组件,且 m ≥ 1。当 m > 1 时,实现了组件化。

组件化,是软件设计中常用的设计方法。

模块

模块,是一些独立具备有效功能的代码,但模块不能在运行时环境中独立运行。一个组件在设计期申明的运行期资源依赖,可以被多个模块所共享。

一个组件可以有 n 个模块,且 n ≥ 1 。当 n > 1 时,实现了模块化。

模块化,也是软件设计中常用的设计方法。

插件

插件,一般不具备独立的功能,直接依赖于运行环境所提供的资源,不能在设计期向运行环境声明外部的依赖资源。插件中包含的逻辑功能,更多的是以「插入」的方式,嵌入到预先设定的逻辑中,以此适应和增强不同的应用场景。

Filter Chain 是一种典型的插件化设计模式。

插件化,同样是软件设计中常用的设计方法。

配置

配置,同样不具备独立的功能,更多的使用场景,是由用户在使用过程中,自行设定的逻辑或者参数值。配置一般不需要编译。