免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: OwnWaterloo
打印 上一主题 下一主题

[C] 思考题:语言是工具?重要是思想?那如何表达思想?(修改版) [复制链接]

论坛徽章:
1
技术图书徽章
日期:2013-09-10 08:57:55
1 [报告]
发表于 2012-03-04 01:05 |显示全部楼层
狗蛋 发表于 2011-10-27 19:12
这里真正需要处理的是动画如何实现、对象如何管理、技能逻辑如何解析、剧本如何解析/执行等等问题:面向对象那一套咋呼并不能解决这个问题,却成功的把人们的视线忽悠到了爪哇国。


以类为例,它仅仅是为了程序设计需要解决的一些特定问题设计,而不是对现实世界或计算机的抽象(图灵机和函数编程不同,它们是对现实和机器的抽象,并且有严格证明);但在宣传时,却把它们当作对现实的抽象进行宣传——甚至,或许这些人自己都没意识到这个问题。

换言之,面向对象本身,就和现实世界的抽象不是正交的,就必然要由此导致问题复杂化;甚至设计者自己,都不知道这东西是对计算机的抽象、还是对现实世界的抽象:说它是什么都可以,可又都不像。

这种混乱甚至达到这样的程度: 面向对象理论不假思索的认为,如果某些东西属于同一个类,或者说满足is-a关系,那么它们就必须有一样的接口。

嗯,好吧,正方形is a长方形吗?如果是,请告诉我它的长和宽!
如果嫌这个还不够刺激的话,人会说话,哑巴是人吗?人有四肢,独臂神尼是人吗?人有心跳,死人能不能告诉我他心跳3下需要多少时间?

要在面向对象的框架里面解决这个问题,除了让人这个基类什么都不会(因而多态也就成了摆设)之外,恐怕就只能搞一些诘屈聱牙的东东打补丁了。这也是复杂性爆炸的一个原因。
当然,这问题用接口(speakable)之类,解决起来就很容易了。
但,不同类的speakable实现可能不太一样:比如聋子说话声音会大、还会吐字不清、口型比较夸张。这样如果每个类都重写speakable的话,继承还有什么作用?
不想重写,难道从聋子和左腿残疾多重继承,以便让一个左腿残疾的聋子说话?嗯嗯,当然,左腿残疾还要从活人继承——从死人继承的左腿残疾貌似也是不可或缺的:这可关系到“滑落的力学分析”和走路的姿势,其中前者死活都一样而后者不同……

好吧,咱不玩了好吧?你没崩溃我都要崩溃了……

不玩多重继承?
退到这里,又失去了面向对象容易扩充的特色,和c已经差不多了。


面向对象设计思路的谬误在于,不是因为一组对象属于同一个类,有了is-a关系,所以就一定有一样的接口;相反,是一组对象支持一样的接口,我们才可以一般化处理同类的东西。

更准确的说,类并不是一个天然属性,而是基于划分方式或者说关注点不同而不同的临时性定义——无论计算机世界还是现实世界都是如此。


说得好.

论坛徽章:
1
技术图书徽章
日期:2013-09-10 08:57:55
2 [报告]
发表于 2012-03-04 10:28 |显示全部楼层
狗蛋 发表于 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#, 为了增加一个新功能, 带出了一串新特性. 不过当时没太注意语言复杂度问题, 就没有保存下来.

用某位牛人的话, 就是"你想要的是一串香蕉, 它给你的却是一只拿着香蕉的大猩猩".
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP