哲思片段 | 设计中的变与不变

古希腊哲学家巴门尼德认为:“人的思想和言语都有一个载体,如果你在这一时间和另外一个时间想到或者谈到同样一件东西,那就说明这件东西在这段时间内没有变化,如有变化的话,你说的就不是同一件东西。”

这让我想起对象的实例。在面向对象设计中,默认情况下并没有约束类的实例是否为可变,这意味着我们可以通过某种方式改变实例的状态。这体现了实例的可变特征。然而,若是站在内存的角度观察实例,则又不然。无论它在内存中存储的状态如何变化,该实例的对象标识依旧是保持不变的。显然,变与不变是相对的。

切换到DDD的命题中,所谓“实体”就是那种具有唯一的可识别可跟踪ID的对象。这个ID并非程序语言在内存中为它分配的对象标识,而是从领域角度来看,由设计者为其识别,由创建者为其分配,因而具有领域语义。实体的状态当然是可变的,然而实体ID在这个实体的生命周期中却是不可变的。

与之相对的是值对象。在DDD中,强调将领域对象严格区分为实体和值对象。一个指导原则是,当你无法分辨某个领域对象究竟是实体还是值对象时,应优先将其建模为值对象。这有助于我们更好地利用值对象的不可变性。

不可变的对象能够更好地维护,因为你不用操心它的值变化,也无需追踪变化的轨迹。不变性天生支持并发。这就衍生出面向对象设计中的Immutable模式。例如Java和C#中的String类型,皆为Immutable模式的实现。

可若放在函数式编程中,这种模式就显得有些可笑了。尤其在纯函数式编程的世界里,任何东西都应该是不变的。

这种不变意味着只要它存在,就不可修改,而且恒古不变。这种追究变化背后的不变性,一直是古希腊哲学乃至科学的基本原则。物质是否永恒不变,在哲学中一直是引人深思的命题或假设;但在函数式编程中,它几乎被证明了。例如,在Haskell中,对List的任何操作,即使调用++对List进行合并,返回的都是全新的List对象,原有对象不会有任何变化。

罗素在《西方哲学简史》中写道:

有的神秘主义者认为永恒并不是指时间上的永久,它是独立于时间之外的,无前无后、无因无果,也没有逻辑可循。

我觉得函数式编程追求的不变性,可以划入这个范畴。

赫拉克利特说:“人不能两次踏进同一条河流”。这是赫拉克利特终极的哲学观,即万物随时在变。软件系统就是这样一条河流,它无时无刻不在变化,正如水不断的流动,需求也总是在变化。但若抛开原子裂变、放射衰变的科学原理,我们似乎也可以将组成整条河流的每一滴水,看做是不变的基本组成要素。这个要素就是Monad中的Identity(幺元或单位元)。这个Identity表达了单一、恒等的概念,例如Int类型中加减法运算半群(SemiGroup)中的Zero,就是一个Identity,因为半群中的任何元素a与Zero结合,依然是元素a本身。

水是如何组成一条河流的呢?这取决于组合子(Combinator)的设计与组合。只要我们找到万物的基本要素,继而设计出各种组合子,就可以演绎出世间不同的物。例如水滴虽可以组合为河流,却也可以组合为橙汁,只要我们加入橙子的另一个组合子即可。这就是面向组合子(Combinator Oriented)的设计思想。显然,它与面向对象的设计哲学背道而驰。

以哲学史观之,函数式思想更符合古典的朴素哲学观。在古希腊哲学家中,泰勒斯认为世界的元素为水,阿那克西美尼认为世界的元素是气,赫拉克利特认为世界的元素是火,而恩培多克勒则糅合了这些思想,认为世界的元素有土、气、火、水四种。而观中国古代哲学,则有五行学说认为宇宙万物都由金木水火土五种基本特性的运行和变化所构成。

不论构成万物的基本元素为何,这种哲学观不正是函数式编程的设计观吗?

原文发布于微信公众号 - 逸言(YiYan_OneWord)

原文发表时间:2014-09-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏专注研发

poj-1006-Biorhythms

人生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为23天、28天和33天。每一个周期中有一天是高峰。在高峰这天,人会在相应的方面表现出色。例如...

791
来自专栏大数据钻研

JavaScript 世界万物诞生记

一. 无中生有 起初,什么都没有。 造物主说:没有东西本身也是一种东西啊,于是就有了null: ? 现在我们要造点儿东西出来。但是没有原料怎么办? 有一个声音说...

3258
来自专栏吴伟祥

学习数据结构的原因&方法 原

601
来自专栏编程

零基础学习人工智能之Python篇1-Python定义

学习Python首先咱要明白Python是什么 定义: Python是一种面向对象的解释型计算机程序设计语言 我们分解下Python的定义,主要是要理解面向对象...

1956
来自专栏Code_iOS

数据结构?

数据结构可以实现一种或多种抽象数据类型,而抽象数据类型(Abstract Data Type [ADT])就是一种数学的抽象,一些操作的集合【插入、删除等操作】...

912
来自专栏C语言及其他语言

【每日一题】1443 [蓝桥杯][历届试题]数字游戏

每日一题,一年365天,想不成为大神都难! 题目描述 栋栋正在和同学们玩一个数字游戏。 游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈。栋栋首先说出数...

3005
来自专栏数据结构与算法

P2712 摄像头

题目描述 食品店里有n个摄像头,这种摄像头很笨拙,只能拍摄到固定位置。现有一群胆大妄为的松鼠想要抢劫食品店,为了不让摄像头拍下他们犯罪的证据,他们抢劫前的第一件...

3716
来自专栏程序员互动联盟

怎样才能学好java?

Java是一种计算机编程语言,拥有跨平台、面向对象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发,是目前用的最广的语言之一,在编程语言排行榜多次...

2695
来自专栏专知

关关的刷题日记10——Leetcode 1. Two Sum 方法1

关小刷刷题10 – Leetcode 1. Two Sum 方法1 题目 Given an array of integers, return indices ...

2879
来自专栏数据结构与算法

P1909 买铅笔

题目描述 P老师需要去商店买n支铅笔作为小朋友们参加NOIP的礼物。她发现商店一共有 3种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平...

3838

扫码关注云+社区