聊聊抽象与建模

软件工程师要有优秀的抽象能力才能设计好软件,抽象能够屏蔽细节,让我们关注要点。不同层次的抽象,关注的要点不同,能够帮助我们解决不同层面的问题。拿软件设计来说,一个具体功能,抽象成具体方法,方法帮助我们屏蔽了实现细节,我们只关注方法的功能;我们把一串相关的功能抽象成类(接口),这帮助我们解决类接口的设计问题;如果我们抬高一个抽象层次,把完成整个业务流程的每个步骤抽象成业务模块、业务节点,这能帮助我们解决模块业务领域复用问题、模块之间依赖关系问题等业务架构层面的问题。

在开始阅读本文前请先思考如下几个问题:

  1. 什么是抽象?什么是建模?
  2. 抽象和建模有区别吗?
  3. 如何进行抽象?

抽象(abstracting)

我们把一堆事物集中在一起做比较,寻找他们相同的点,这个过程就是抽象(abstraction),而抽象的结果是概念(concept)。
例如:

牛顿、爱因斯坦,可以抽像出 的概念,
牛顿、爱因斯坦、蜜蜂,可以抽像出 动物 的概念,
牛顿、爱因斯坦、蜜蜂、桌子,可以抽像出 东西 的概念。

有没有发现,当不同的事物在一起对抽象的结果会有影响。这里的例子看出抽象出的概念越来越模糊了。这就需要我们在对事物抽象前进行分类。

分类

分类的目的是为了防止抽象出的概念太模糊,导致价值很低,我们需要把这些想要抽象的东西根据某些共有特性进行分类(classification)。
比方说,我们需要开发招聘网站系统和医院的病人管理系统,他们都需要对人进行管理。张三想求职(应聘人)、李四想看病(病人),我们需要他们相关的信息记录到系统中,但并不是事无巨细,不同的业务关注点不同。
招聘网站对人关注的:姓名、年龄、联系方式、职业经历、学历、语言等等。
病人管理系统对人关注的:姓名、年龄、联系方式、病史、药物过敏史等等。
你会要张三在填写应聘信息把药物过敏史也写上去吗?会不会很奇怪?
所以我们在进行分类的时候,我们必须明确业务目的,排除不关心的、干扰的事物。就像上面的例子,如果只抽象出人的概念明显太模糊,招聘网站应该关注应聘人,排除病人的干扰,同时也应该排除两个眼睛、一张嘴这些一样的信息。

概念

概念是有意义的,概念本身可以单独存在。概念的内容包括所有一个组成该概念的事物的特性和关系。概念是抽象的、普遍的想法,是充当指明实体、事件或关系的范畴或类的实体。
比如铁路运输使用铁路运单,航空运输使用航空运单,多式联合运输则使用联合运输单据。所以 运输单 概念的内容包括所有有关这些单据所有的特性。人们在定义这个概念的时候会挑选出这些特性的关键部分,比如,运输单据通常是指代表运输中的货物或证明货物已经付运的单据,它具体反映了同货物运输有关的当事人(如发货人、承运人、收货人等)的责任与权利,是货物运输业务中最重要的单据文件。
概念在它们的外延中忽略事物的差异,如同它们是一样的去处理它们,所以概念是抽象的。

类型

什么是类型:在概念的基础上扩充对某些关键信息的要求就是类型。也就是说,某个事物想要属于某种类型,就必须满足这个类型的概念,同时提供这个类型要求的关键讯息。
比方说,我们在对铁路运单和航空运单进行抽象时候,已经抽象出运输单的概念。现在我们要区分不同运输方式的运输单据,是铁路运单还是航空运输,所以我们扩充了运输方式这个关键信息。
铁路运单是一个概念(有自身的意义),也可以是一个类型(除了运输单这个概念的意义,还必须要有运输方式的信息)

建模(modeling)

建模是过程,模型是产物,模型是用来描述事物的。

模型的价值

  • 作为沟通的工具,传递想法(就像地球仪、建筑蓝图)
    • 因为实际的事物,或者你脑海中的想法,通常都非常复杂或模糊,难以让其他人理解
    • 对于软件来说包括系统设计和架构设计
    • 对于企业组织包括组织架构和流程设计
  • 是事物进行迭代设计的工具,有助于改进设计、研究事物演进过程
    • 由于实物的变化,成本高,而对模型的改变,更容易、经济
    • 通过对模型的调整,可以推演出适合的迭代轨迹
    • 对于软件来说就是重新工程化的设计
    • 对于企业组织就是企业架构和业务调整过程的设计

建模的要点

  • 时刻明确目的,记录和目的相关的要点(profiling)。例如为人建模,如果目的是为了就业,那么技能、兴趣等信息很重要;但是如果目的是健康,体重、血压很重要。
  • 只记录有差异的点,才能精简。例如为人建模时,要把两个眼睛、一张嘴这些一样的信息排除。这就是抽象的问题了,人是抽象的结果。

总结

  1. 分类的目的是为了更好地抽象,抽象的目的是更好地建模,良好建模的第一个重点在于记录业务目标的相关要点。
  2. 抽象的产物是归纳出概念(属性),并为了突出关键信息,将概念扩充为类型。
  3. 对事物进行建模的过程是,一堆事务先分类,不同分类的事物分别建模。分类后的事物再抽象得到事物的概念,在将概念扩充为类型,最后将事物概念里需要的信息,结合实际物体信息填充,得到具体事物的模型。
  4. 建模(modeling)和抽象(abstracting)是不一样的。建模是对某一个(或某一类)事物描绘要点(profiling),重点在找出特殊的属性值;抽象是对某些事物找出共性的概念,重点在找出共有的属性,而非属性值。所以说现要抽象,才能建模。
  5. 建模是过程,模型是产物,模型是用来描述事物的。
  6. 建模前需要明确目的,只记录有差异的属性值。差异的寻找是是通过对一类事物进行抽象,归纳出属性列表,对照属性列表记录有差异的属性值。
  7. 反过来想,当我们学习新知识的时候,可能先知道了某个概念名词,我们需要思考这个概念是对什么事物(问题)的抽象,这样有利于我们对新知识的学习。比方说 CAP 这个概念是对,是对分布式系统特性的抽象;ACID 是对事务特性的抽象。

扩展阅读

《建模的重要性》《抽象和类型》