一 世界的本质
状态(数据)变化是一切现象的本质,这是宇宙的本质,所以也是程序的本质(三段论学的不错XD)。
宇宙的本质:
可以理解为物质状态(数据)在不同时间点的演化,即构成了过去,即已知的宇宙,信息数据以“历史”的概念来存储(未来?那是推演的模拟结果;而现在也总在成为过去)。
程序的本质:
即对数据(数据结构)的增删改查/读写(算法)。
如果你同意这一世界观,那么可以继续往下看!
二 信息的分层思想
在描述过程序的本质之后,我们便可以谈谈如何对信息进行分层了。
分层的思想可以通过《道德经》里的一句话来诠释其质朴的道理:
天下大事必作于细,天下难事必作于易
我们这里讲的是一种信息的深度层次,是纵向的,也就是有先后依赖关系的。而随着这种深度的增加,需要考虑的依赖关系复杂度是非线性的(阶乘级O(n!))。
PS:复杂度随广度增加,一般是线性或者常数级的。
当前的架构分层模型有:MVC,PureMVC,MVP,MVVM等。
MVC是最经典质朴的架构分层模型,其他分层模型都是这一理念的拓展,如果复杂度的提升是必要的,那么付出必须获得大于等价的回报才是有意义的。
PS: 当然极端情况是,项目足够简单,不需要考虑分层,顺着大脑的思路一路写下去就完事了,这也是早期做项目的方式。这也从侧面说明,说设计来源于现实需求。
View:视图(数据状态的展现 == 数据进行算法活动结果的可视化呈现)
Controller:控制器(数据增删改查 == 算法)
Model:数据模型(元数据记录形式 == 数据结构)
但是不管架构分层模式怎么设计,都不能脱离“以数据为中心”这一原理,否则就会跑偏,就很容易导致数据在真理的单点性原理(SPOT: Single Point Of Truth)上的失效。
《UNIX编程艺术》中提到,真理的单点性原理:即一个对象的定义只存在一个唯一,准确,权威的解释。
三 依赖关系的建立方式:接口,事件,消息
你是否纠结过,一条广播只有一个接收对象,那是不是和广播的定义不是那么匹配,不广播又违背了解耦的原则。
你是否因为广播或者回调需要带参数,而参数又比较多的情况下,不得不构造一个特定的结构来存储数据,而这个结构的作用也就仅限于此。
OK,你说还可以选择不定参数类型,那么对于不定参数类型的理解不直观和打印时的繁琐是不是也产生过一些失望呢。
如果曾经为此有过刻骨铭心的纠结,那么可以再继续往下看!
首先解决参数绑定方法和消息的问题,因为带参数,所以其实是事件通知和数据传递耦合在一起了。
如果你同意这两者应该解耦,而且可以大大简化编程的复杂性,那么再继续往下看!
到此我想大家是不是隐约开始意识到,围绕数据而不是分层的形式化来设计框架模式,也许才能使得以上问题有解。
四 MVC模式设计
我接触到的理解千奇百怪,但最主要的是M和V的解耦,即一般都是完全隔离的,如下图:
我认为这并没有结合工程实践,分层的目标首先当然是隔离,但是依赖关系却并不是最终建立联系的标准,而读写关系才是。既然MVC都是基础设施,那么如果不让V知道作为基础设施的M道理何在,只是为了隔离而隔离就太形而上学了。
我的结论:V可以读M,但V不能写M。
这么设计的实践基础是:工程内部的逻辑对象和元数据的交互方式。1:直调(接口),2:回调(事件),3:消息(广播),而这几种信息交互方式,很大程度上决定了工程的复杂度,不夸张的说,这几者方式的定位不清晰是效率低下工程的罪魁祸首。
在使用率上,消息广播 < 回调 < 直调(最值观,理解成本最低)所以可以建立规则:1 只有全局数据更新,才使用广播,其他时间一律不广播;2 只有异步操作才回调;3 除上述两种情况外全部采取直接调用的方式。
遵循一个大原则:这三种访问方式本身都不携带元数据。
副作用:不影响结论,待补充…
通过这种设计你能发现带来的好处是极大的,首先阅读成本大大降低,其次能轻松实现“真理的单点性原理”(因为数据传递过程中不得不小心处理值类型和引用类型),大大降低了项目开发人员的心智负担。
参考