抽象化,是数学的一种研究方法。
使用得当,则能扩大我们的视野,有助于看清问题的本质,
可是,有时候我们也会被抽象所累,使解决方案变得更复杂。
在数学中,站在更高的角度看问题,是司空见惯的事情。
而且从每个层级来看,都可以再次抽象,站得更高。
例如,从实际问题到线性方程组,从线性方程组到矩阵运算,
从矩阵运算到抽象代数,从群环域再到范畴论;
从实际问题到计算过程,从计算过程到它的描述方式,
从描述方式到形式语言,从语法和语义再到形式逻辑。
两个极端
虽然数学有其自身的研究目的,
但是,在现实生活或者应用工程中,都把数学当做工具来看。
人们大多数的时间,都在解决具体问题,
看清问题背后的数学结构似乎毫无意义。
其实不然,这是其中的一个极端,
忽略了全局性思考和洞见所起的作用。
另一个极端,是试图总将问题抽丝剥茧,
也会引入不必要的层次性,使解决方案不够切题,
毕竟具体情况的特殊性和复杂性,才是主要特征。
编程就是考虑了这两个极端之后权衡的结果,
我们既要为现实问题建立模型,简化它的描述方式,
又要适度的建模减少逻辑层次。
不进行抽象是不行的,过度抽象也是不行的,
我们应该怎样做呢?
封装
软件领域,有一个概念称为“封装”,
可以让我们把复杂性隐藏在某个“界面”之下,
使用这个“界面”的人,可以不关心内部的实现细节。
这给我们提供了一种思路,
让我们可以在保持内部层次性的同时,
给最终用户提供朴素的“界面”,把锋芒藏起来。
此外,“使用者”和“提供者”只是相对的概念,
内部的各个层次分别扮演着这些角色,
上层提供普适性的功能,下层作为使用者来具体化应用,
层层具体化,抵达最终“界面”。
这种方式确实能让软件变得灵活,提高扩展性,
在需求不断变更的驱动下,最高层的适用范围会越来越广,
新出现的场景,都将成为某一层次不同具体化的结果。
不幸的是,随着层次的增加,逻辑深度也会增加,
理解整套方案会变得越来越困难。
我们提取出抽象,本来想让它具有普适性,
能用于更多类似的场景,
可悲的是,通常也是只适用于当前场景罢了。
选择不做
经验告诉我们,我们如果不做一件事情,
往往不应该是我们没有看到它,
而是应该在会做的同时,选择不做它。
因此,与其说选择影响了结果,
不如说,眼界影响了选择。
上文提到,那些貌似普适性的抽象层给我们带来了麻烦,
如果不带来任何价值,我们就应该去掉它,
容忍它以普适性的身份混杂在具体应用中。
能看到选择,却选择保持原样,
不仅需要卓越的眼光,还需要不凡的魄力,
心中追求完美,但是眼中要能容忍不完美,这才是关键。
结语
我们都学过设计模式,想过优化自己的设计,
于是就容易走入极端,
我们变得无法容忍拙劣的设计了。
我们总想去调整它,去完善它,
可是却无意中增加了设计的精密程度。
为了不暴露这些复杂度,于是我们学会了掩饰它,隐藏它。
可是,仅仅这样并不够,
我们细心的打磨零件,想让它在任何一台机器上都能被使用,
最终也只能用在这里。
因此,好的办法是,我们看到这样的零件存在,
但是却不总是想着孤立它,战胜强迫症。
我们看到了背后优雅的数学,却不总是提及它,
大智若愚不如虚怀若谷。