OOA/D 01

建筑师一般不会为一栋100层的楼添加一个新的地下室,因为成本太高无疑会失败,但软件系统里提出类似改动需求时,他们通常都不会多想一下,相反他们会说:这只是一个简单的编程问题

可总会有一些看似极难完成、但却是市场所需的的需求,它可能会让你感觉需要推倒重来,这是我们不得不面对的问题

如果我们能在建造之初就预料到以后的“地下室需求”,或者希望对以后未知的需求有丰富的扩展体系,这就是OOA OOD的价值。举一个不切实际的例子,按照对建筑行业的通用认知,建造时先挖个3层高的洞放在那,先不管以后用作什么,未来是不是就可以很轻易的添加地下室或其他东西呢?

当然了,如果要把地下室改成飞机跑道那就还是无解,这属于畸形业务、畸形需求,并且已经跨领域了,经验再丰富的分析师也没有办法解决,只能推倒重来

 

顺带一提,OOA ,OOD,OOP,他们正是DDD的基础支撑,不严谨的说,DDD是他们落地方法论的一种,但OO最大的问题在于一股脑去体现 "结构"的表达,而DDD丰富了他们,其中最主要的是丰富了 "行为"的表达

 

  复杂性

  人在处理复杂事物时有自身的能力局限,如航空交通控制系统,必须同时处理不同飞机的状态、面对相当大的、交错的、非确定性的等等状态空间,一个人绝对没有办法跟踪所有细节

  一些心里学家实验表明,人能同时理解的额最大信息数量是7个左右,大脑需要大约5秒才能接受一组新的信息,并不仅仅只有程序员是金鱼的记忆,所有人都是如此

  工业级软件所涉及的问题域本身太大,单个开发者要理解它设计的所有方面太困难,甚至可以说这些系统的复杂性超出了人类智能范围,虽然我们可以掌握这种复杂性,但无法消除它

 

  现状

  简单的系统不谈,基于复杂系统的层面上,开发初期

  需求方很难用开发者容易理解的方式对需求给出准确的表述,常见的方式是用一大段文字描述、偶尔配有草图,这样的文档难以理解,因为双方都缺少另一个领域的经验,双方完全站在了不同角度看待问题。甚至有时候连文档都没,仅凭需求方短短几十分钟的口诉,换来的就是程序员的胡乱猜测

  还一个问题是,程序员缺少了系统的、合理的分析与设计方法,只将看到的东西如实反映在程序中,虽然头几个版本也许美食,但经过多个版本迭代后,代码的混沌也就慢慢显露了,这是没有对未来进行预判的结果,或者进行了预判但没有使用正确的设计方式

  结果就是,当程序员开发完成后,用户、需求方在经过使用之后会对需求有更好的理解和表述,同时这个过程也帮助开发者了解了问题域,使他们能问出更好的问题,从而发掘出隐藏着的、需求方没有表露出来的真实需求、隐藏需求,然后程序员再对系统进行不堪入目的改造

  这种改造的过程是一直循环的,企业成本明显提升,老板抱怨程序员任务完成周期太长。程序员自己也痛苦,抱怨需求变态。当然,这种问题无关某一方的对错,需要天时地利人和(愿意花时间沟通业务、愿意给时间做设计等),才能在最少的改造次数下完成

  一般来来说,修正错误是维护,应对改变是演化,而当我们使用一些极端手段来保持系统能继续工作时,这是保护,目前看来大部分开发者在面对修正或改变时,不得不同时进行保护

 

  分而治之

  分解系统的空间状态,可以直接解决软件的复杂性,更好的理解与设计系统

  目前的分解方式有两种,一种是算法分解,一种是面向对象分解,不能说哪种好哪种不好,在不同的阶段不同的场景都有各自的重要性

  对于一个系统,最开始能接收到的信息只有一份基本需求,里面有所需的业务描述,下手的地方就是阅读,找出各种名词动词词语

 

  算法分解

  算法分解强调事件的顺序,围绕业务的动词建立起来,它是一种自顶向下的结构化设计,这导致了程序具有树的形态,面向了过程

  当系统代码数量太多,比如超过10万行时,这种方式似乎就不行了,因为各处耦合而不利于伸缩,尤其是对于复杂系统

  但用于某一具体场景时,却可以很直观的看出各流程节点逻辑、关系

 

  面向对象分解

  面向对象分解强调了代理,根据问题领域中的关键抽象概念对系统进行分解,每个对象都是真实世界某个对象的模型,它们要么发出动作要么就是这些操作执行的对象

  通过复用共同的机制得到一些较小的系统,提供了更加低成本的表达性,作为真实世界实体的抽象,语义上也更加贴近业务,自身又代表了一块密集又内聚的信息,将巨大的状态空间进行关注点分离,直接关注了软件的内在复杂性

  并且,对象模型在规模上可以扩展,一组抽象可以构建在另一组抽象之上,可以用更加宏观的视角来观察分析

  它围绕各种类型的词语建立起来,具体说来,比如名词代表某一对象动词代表对象的行为动词词组代表关联并可能引申出场景,对象又需要分析它的结构,对象与对象之间可能又共享某一场景,这又需要合理的组织,等等等等

  

  结构

  植物包含三种主要结构,根、茎、叶,他们各自又拥有不同的特有的结构。例如根包含支根、根毛、根冠,叶有表皮、叶肉、纬管束

  这些结构又由一些细胞构成,每个细胞内还可以发现另一层的复杂度,如细胞核等

  他们的各个部分组成了一种层次结构,层次结构中的每一层又都有着各自的复杂性

  植物细胞由刚性的细胞壁包围,但动物细胞却不是如此,尽管存在着差异,但不管怎么说这些结构都是细胞,这是跨领域共性的一个简单例子

 

  组织

  发现共同的抽象和机制可以促进对复杂系统的理解,一个有经验的飞行员,可以很快学习驾驶一架从未驾驶过的飞机,因为飞行员在学习之初就已经了解了他们的共同抽象:舵、节流阀等,只需要花点时间去学习这架飞机的特有特性:比如哪个按钮发射导弹之类

  其实这说明层次结构的使用方式是很宽泛的,复杂系统往往有许多不同的层次结构

  分析PC主机时,我们可以将它分解为主板、显卡、CPU等,这是一种结构上的层次结构,或者说组成部分的层次结构

  而换一种方式分析,GTX980与HD4600都是一种具体的显卡,显卡代表了他们的共同抽象,这代表了"是一种( is a )"的层次结构,他们又有一些独有特征,比如GTX980可以运行很多大型游戏而HD4600却不能,这能帮助我们进一步掌握它们内在的复杂性

  我们可以把这些结构分别称为"类结构" 和 "对象结构"(并非具指代码中的类和对象)

 

 

  ( 面向对象分解的建模 )  

 

         

 

  (附加了四色原型模式的对象建模)

  

 

posted @ 2019-03-11 00:13  韬韬韬你羞得无礼  Views(230)  Comments(0Edit  收藏  举报