- 论坛徽章:
- 1
|
狗蛋 发表于 2011-10-28 11:11
补充: 上面的例子是new关键字和旧类型初始化之间的耦合;还有new运算符和内存分配方式(如栈分配、内存池等)之间的耦合,这就是所谓的placement new和new运算符重载等概念。
——这类东西,在很多微软式封装或初学者架构中比比皆是。
——它们的共同特点就是:给你一个看似很爽很漂亮的封装;但当你真的去用它时,就会发现自己不得不去窥探这个封装里面的东西;更恶心的情况是:这种封装往往还会近乎“恶意”的阻止你去接触内在的东西……
嗯嗯,封装不是把不希望别人看到的东西藏起来吗?
我并不这么认为。
封装不是简单的把不希望别人看到的东西藏起来。这样的东西是恶心的微软式封装,它教唆、逼迫使用者去寻找“未公开的系统调用”之类东西,因为这种不公开的东西往往反而是能不能实现某个功能的前提。
这种现象的原因,是这些模块本质上是基于非正交的模块划分而设计的;而“非正交”这个属性,就决定了该模块本质上不是独立的,不为它(和其它部分之间)的交互设计特例,就不可能完成期望的功能;而这种特例会破坏封装,于是不得不将其“未公开”,以保持表面上的光鲜,并期望将来某个时候也可以将其纳入管理(或者说,搞另外一个表面光鲜的“封装”)。
相反,图灵机、函数式编程,甚至C内部的绝大部分概念都是正交的。
正交的东西才可以独立分析,才可以在学习/使用一个关键字时,完全忘掉其它关键字。这就叫xx概念对其它部分透明。
我认为,“对其它部分透明”,是可以“隐藏私有实现”的前提。
很可惜,new对于c++的其它部分显然不是完全透明的。这就是之所以衍生出new[]、operator new、placement new的根本原因。
当然,这可以说成是“为了兼容c”和“为了兼容c以及用户自定义内存分配模型”而不得不付出的代价。
但,至少new和其它部分不正交并因此导致了几倍的混乱,是不争的事实。
——嗯,之前考虑不够细致,不能准确说出我的确切想法。现在可以尝试说的更确切一些了:关键字/特性的多少或许并不和复杂度挂钩,但硬生生插进体系的、和其它部分非正交的关键字/特性将导致复杂度指数级增长。
如果可能,就将这种新特性置于考虑范围之外。等到实现时、确认不会引起棘手的side effect前提下,能用就拿来用,不失为好的选择。
但如果在设计之初就考虑这些东西,就必然不得不去窥探它的内部实现,进而导致诘屈聱牙的东西出现。
这,或许就是c++名为c之超集——c有它都有(且完全兼容毫无额外负担还提供了类型安全等等等等免费午餐),c无它也有——但市场占有率上反而玩不过c的原因吧。
前一阵我也看过一个类似的例子, 是java还是C#, 为了增加一个新功能, 带出了一串新特性. 不过当时没太注意语言复杂度问题, 就没有保存下来.
用某位牛人的话, 就是"你想要的是一串香蕉, 它给你的却是一只拿着香蕉的大猩猩".
|
|