OOP代码能做什么,而程序性代码不能? - 页 3

 

在小规模的项目中,你可以证明任何问题都可以被分解成程序代码。然而,当你有几百万行的代码库,有100多个开发人员的团队,几个业务分析师和架构师都想同时对 "模型 "进行修改时,事情就变得很困难了。在这种情况下,"业务 "模型通常被定义在UML这样的设计工具中,并且整个团队都可以访问。

仅仅业务模型就包含5000多个类。从这个业务模型中,有一些工具可以为对象模型、SQL接口和网络层 "生成 "类,使基线类数达到15,000类。

在这次讨论中,我想把程序化与OOP的争论分解成三个 "扩展",自1960/1970年代以来,这些扩展被添加到程序化中。

1) "基于对象",即对象和代码被封装成高级 "结构",也可以有行为。

2) "基于类",即对象可以相互继承,并在层次结构中排列。

3)"面向对象",用户可以在类的层次结构中定义 "多态 "行为(虚拟方法或接口)。

有一种观点认为,只要付出足够的努力,上述所有内容都可以在过程性语言中实现,例如,80/90年代的大多数GUI工具包都是用c语言创建的,并具有这些功能,但这些功能对于普通的编码人员来说并不容易实现,因此并不真正适用于本讨论。

那么,为了回答这个问题,我们能不能在不使用这3个OOP特性的情况下实现一个有100多个开发人员的数百万行的项目?

我的个人观点是,如果没有1)和2),几乎不可能完成一个大规模的项目,因为如果没有一个 "基于类 "的系统,就很难将现实世界的数据结构 和行为以一种简洁的方式映射到代码中。更重要的是,随着项目规模的扩大,一开始的 "我们可以用c语言实现 "变成了无尽的方法列表,结构越来越少,维护起来也越来越困难。

现在,那些只提供1)和2)的语言并不是完全的OOP语言。所以我们应该考虑 "多态(虚拟)方法 "是否真的有必要。这有点像 "也许",或者 "有时",因为多态性并不总是解决问题的正确工具,而且会使设计过度复杂化。例如,当对一些映射到对象存储或SQL数据库的数据结构进行建模时,添加虚拟行为会使数据映射更加困难,但是当定义可扩展工具包或API时,使用 "接口 "或带有 "虚拟方法 "的基类是非常有价值的。总的来说,我是多态性的忠实拥护者,只要在正确的情况下少用,就可以了。

我曾经参与过几个几百万行的 "C "代码库和几个几百万行的C++/Java/C#代码库,大多数 "C "代码库在5年后就进入了 "维护模式",因为开发人员害怕改变结构,因为代码太脆弱了,修改往往导致几个月的痛苦的再开发和测试。一般来说,面向对象的项目对修改和重构的适应性要强得多。

 
Alain Verleyen:
"if...then...else... "语句应该可以完成这个工作。

if...then...else不能够对 "虚拟 "方法进行编码。

在 "C "中,有几种 "多态性 "的实现方式,其中大多数使用函数指针 的向量来保持必要的映射。更重要的是,这些 "函数指针向量 "需要为你想在 "层次结构 "中建模的每个 "类型 "进行定义。当然,"C "并不直接支持层次结构,所以你也必须解决这个问题。

如果你真的想进入用 "C "实现的 "虚拟 "方法这个麻烦的袋子,那么你可以挖出X Windows工具包,这些工具包在每个Linux发行版中都是免费提供的。

当然,Windows必须稍有不同,它使用了带有整数消息ID的可扩展结构。 这意味着 "多态 "行为是通过ID的开关语句实现的。(可能是最肮脏的方法,但它会让你达到目的。)

 
Alain Verleyen:

你同意Windows操作系统提供了一个良好的图形用户界面吗?据我所知,它是用C语言写的,是程序性语言,不是OOP。

如果你认为一个复杂的程序只能用OOP编写,那你就错了,Dirk。你应该解释一下为什么用OOP编码更好。

Windows内核 是用 "C "语言编写的,但内核只是Windows代码库中的一个小部分,许多高级代码库都是用C++语言实现的,有 "C "风格的外部接口来支持多种语言。

即使是传统的Windows GUI组件也实现了他们自己的手工滚动的 "多态行为",这实际上是用 "C "实现的 "OOP"。例如,当你从GUI控件中得到一个 "手柄 "时,你得到的是一个可扩展的 "C "结构,并有多态行为可用,这就是OOP,只是用一套丑陋的 "C "语法包装起来。

说Windows不是OOP,因为它是用 "C "写的,这并不完全准确。

 
Alain Verleyen:

我不会用过程性语言建立一个GUI来证明你是错的。但我可以毫不怀疑地证明。

顺便说一下,在OOP中也很容易写出不可读的、慢得多的代码,正如你所知道的,Metaquotes标准库 就是一个很好的证明。

OOP比程序性代码慢得多,这完全是一个神话。许多OOP项目之所以慢,是因为它们设计得很差。虚函数调用的开销比你想象的要小得多,尤其是现在的芯片内存获取架构,可以并行查询和执行。

https://hbfs.wordpress.com/2008/12/30/the-true-cost-of-calls/

引用上面链接中的一句话:"但是调用的成本,不管是什么味道,都是由其参数的评估所主导的。我们看到,间接调用,无论是C-style还是C++的虚拟方法,本质上都是便宜的。对虚拟方法的调用并不比使用结构成员的间接调用(something->function(arg1,arg2))更昂贵,所以认为虚拟函数慢得惊人只是误导。"


Java可能比C++慢很多,因为每一块封装的数据本身必须是一个基于堆的类,所以你确实得到了更多的对象解除引用。然而,即使Java在循环和基本的数学运算中也可以和C的速度完全一样。

如果你将C和C#进行比较,确实很难写出一些在C与C#中明显更快的代码,即使你包括一些OOP的特性。

如果Metaquotes标准库很慢,那么90%是由于库的设计特点造成的,与使用的OOP特点关系不大。

(作为比较,C++标准模板库的性能比任何C项目的95%都好。)

 
James Cater:
...

谢谢你的巨大贡献。

 
Alain Verleyen:

谢谢你的巨大贡献。

谢谢,我不是在嘲笑你,只是你是唯一一个支持程序性论点的人 :)
 
James Cater:
谢谢你,我不是在嘲笑你,只是你是唯一一个支持程序性论证的人 :)

不用担心,我必须扮演好 "主持人 "的角色。

 

当然,如果能看到你们这些人所谈论的一些例子就更好了。对于那些有经验的人来说,谈话/打字都是好的,但我是一个视觉上有经验的学生,请公布例子。

我在犹豫是否要继续学习mql4,转到mql5,或者干脆用其他平台。

谢谢Alain发起这个话题。这个论坛真的需要这个。

 

你真的指望一个专业人员发布一个compex库,就这样作为一个 "证明"?)我可以给你一个链接,让你看到一些在这里的市场上无法出售的东西,但如果我这样做,阿兰会踢我的;)你可以访问我的个人资料,看看墙上的图片,以获得一个想法,或者给我发个邮件。

另一个平台?你不会找到任何其他平台有如此强大的编译器。一点也不。

@James Cater - 非常感谢你的评论。

 
Doerk Hilger:

你真的指望一个专业人员发布一个compex库,就这样作为一个 "证明"?)我可以给你一个链接,让你看到一些在这里的市场上无法出售的东西,但如果我这样做,阿兰会踢我的;)你可以访问我的个人资料,看看墙上的图片,以获得一个想法,或者给我发个邮件。

另一个平台?你不会找到任何其他平台有如此强大的编译器。一点也不。

@James Cater - 非常感谢你的评论。

你忽略了德克的观点。非专业人士希望有简单明了的代码例子,这实际上是我这个话题的目标。但这似乎完全超出了专家的理解范围。