OOP与程序化编程 - 页 23

 
Maxim Kuznetsov:

看来你错过了聊天:-)版主们已经钳制住了燃烧的话题......但这里是OOP对战。

顺便说一句,@Peter Konow的 99%都使用OOP,但他并没有意识到这一点 :-)OOP不一定是 "类和模板"。

反之亦然......程序中存在对象和类并不表明是OOP。

这是一个非常有趣的想法。也许是这样,而我并不怀疑。))


但你怎么知道呢?

 
Реter Konow:

这是一个非常有趣的想法。也许是这样,而我并不怀疑。))


你又是怎么知道的呢?

例如,OO可以通过消息调度来实现(并且有一些类/模板MQL中没有的 "优点")。

我还没有看完你的代码,可能也看不懂,但既然你有GUI库,我肯定它有自己的(至少一个)队列,通过对事件/发送/状态的处理,它都被包裹起来了。而这种非常的 "扭曲 "到头来只是继承/多态性。

 
Dmitry Fedoseev:

关于刺猬。

"刺猬 "站在空地上,摆出姿势,弯曲他的二头肌。- 我很强壮,我很勇敢,我很敏捷,我很强壮,我很勇敢,我很敏捷...。

一只熊走过--踢了他一脚,刺猬飞到树后,站起来,抖了抖身子。

- 我很强壮,我很勇敢,我很敏捷.........但我很轻...


正如我儿时的朋友常说的,刺猬是一只骄傲的鸟,如果你不踢它,它就不会飞))
 
Alexey Volchanskiy:

乔治,我今天和一个女孩去散步,我们聊了一会儿,我们想起了一些关于害羞的男人。说实话,我不打趣,每个人都有不同的性格和不同的成长经历。

哦...而莱卡是为小鸡准备的......这也是正确的。比美国共和党有趣多了。

嗯,我的问题不是害羞。我唯一可以夸耀的是 "挂好的舌头"。我的问题是阴道中心主义与无钱的问题。我太看重隐私和性了。你在上面写道:"......我已经看到,当美丽的女人在前面晃动时,男人可以多么努力地工作。"好吧,我是这些人中的一员。除了,小鸡们,他们需要你,而你是年轻、强壮和富有的。而如果一个小妞有机会把你干翻,她迟早会把你干翻。即使是一个年轻、强壮和富有的人。 我是一个身无分文的老残废,没有家。所以我的机会是零......我甚至不惊讶我妻子的离开。只是你似乎并不关心你已经离婚了。另一方面,我发现我无法创造条件让我的妻子无法离开,这让我感到非常沮丧。

 

而关于OOP...

如果我有和Retag Konow 一样的记忆力 也许我会同意OOP是不必要的,建立所有这些接口、类、对象、继承系统和虚拟函数有什么意义呢?

阿列克谢正确地说--处理器对任何物体都一无所知......它甚至不知道什么是功能。这证明了任何任务不仅可以不用OOP,甚至可以不用函数来解决,只需记住返回地址,通过IP寄存器(或现在使用的任何现代CPU)来传递控制。

我不理解Retug Konow的 立场,直到他给我看他的代码。现在一切都清楚了,我甚至可以同意他的观点,如果我设法把这一切都记在脑子里,长长的如果不打扰我的话,我怀疑按照他的方式写更合理。此外,在这种情况下,OOP真的成了 "车中的第五个轮子"。

但是,就我个人而言,我的问题是,大多数工作的细微之处--它在我脑海中滑过。例如,我总是忘记多维数组 G_CORE中的每个索引负责什么;在给定片段的每个条件中,我每次都会认真思考--它定义了什么。对我来说,分析长期状况也将是紧张的。

而有时我自己写的这种代码也很难理解。这是我的"不正确"代码的一个片段,我以同样的方式下沉(我在上面引用了它)。

virtual bool IsTPCInUnloss() const { if(GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE) return(false); if(GetTPCType() == POSITION_TYPE_BUY) { if(GetTPCStopLoss() >= GetTPCOpenPrice()) return(true); } else { if(GetTPCStopLoss() <= GetTPCOpenPrice())return(true); }; return (false); };

这是CTradePosComponentI交易组件接口函数,它决定这个组件是否处于盈亏平衡状态。

"这段代码的 "错误 "在于,这里牺牲了可读性,而牺牲了紧凑性和可读性。因为功能包含在界面中--如果可能的话,我希望整个界面能在一个屏幕上看到。只是为了让我不必记住它提供了哪些功能,以便所有这些功能都能一次看到。如果我记住了一切--就没有必要将函数 "拉伸 "成一个字符串。因此,该功能在十几行上伸展开来--很好......然而,对我来说,重要的是所有的功能都能在界面上相互配合,而且所有的功能都能被看到。我希望看一眼界面就能立即对它提供的一系列功能有一个概念。这就是为什么--我不得不用一长行写出这些功能。然而,要理解它是完全不现实的。

最初,在写代码的时候--我一开始写这个函数的方式很不一样。以明确的方式和评论。这样我就能理解它。

像这样。

virtual bool IsTPCInUnloss() const 
{ 
    // Отсеем вариант, когда СЛ отсутствует
    if(GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE)
         return(false);

    //  Проверим тип торговой компоненты
    if(GetTPCType() == POSITION_TYPE_BUY)
        { 
        // Торговая компонента - лонг
        if(GetTPCStopLoss() >= GetTPCOpenPrice())
            return(true);
        }
    else
        { 
        // Торговая компонента - шорт
        if(GetTPCStopLoss() <= GetTPCOpenPrice())
             return(true); 
        }; 

    return (false); 
};

只有在所有这些都经过测试和调试之后--代码才会被清除掉注释,并 "拉成一条线"。

但这是一个例外。我很少这样做,在 "可见度 "很重要的特殊情况下。在所有其他情况下--我写的代码既 "宽 "又有缩进,而且在任何地方都有注释,在那里可能会有 "这里有什么 "的问题,有最轻微的障碍。

否则,我很快就会忘记在哪里,做什么,为了什么。

 
Maxim Kuznetsov:

例如,通过消息调度,OO是相当可行的(而且有一些类/模板MQL中没有的 "优点")。

我没有看过你的代码,也读不懂,但既然你有GUI库,我肯定它有自己的(至少一个)队列,通过对事件/句子/状态的处理,有很多事情被搞砸了。而这种非常的 "扭曲 "到头来只是继承/多态性。

好吧,既然我已经说了 "A",我也想说 "B")。我将更具体地描述我的技术。

通过将从事某类任务的功能组合成大块,我减少了需要在各功能之间建立的链接数量。这有其优点和缺点。

首先是关于专业人员。

在OOP中,一个机制被分解成大量的功能,需要创建许多对象来连接类和结构。同时,每个函数原型周围都有大量的形式参数,函数通过这些参数与周围的代码进行交流。正是因为在这个机制的发展过程中,机制各部分之间的联系增加,代码的内部结构变得更加复杂。

在我的技术中,函数和块之间的通信完全通过使用全局变量来简化,全局变量贯穿始终。函数不需要传递参数,因为它们在全局层面上立即看到参数。

全局变量的值 是由 "跟踪 "光标的 "对象焦点 "块设置的。它使用光标的当前坐标来确定鼠标集中在哪个对象上,并访问存储所有元素、对象和窗口的所有属性的内核(G_CORE)。从内核中,该区块获取光标下对象的所有主要属性的当前值,并将它们放在全局变量中。如果光标在对象上移动,全局变量在这个区块中被重新定义,并且总是对应于处于焦点的对象。

接下来,OnChartEvent()函数会捕捉那些应该改变光标下元素状态的图表事件。在这些事件中,状态控制块(它被整合到OnChartEvent()本身)立即看到哪个窗口、元素和对象处于焦点,以及它们的属性是什么。你不需要向这个块传递任何东西,因为你需要的一切都已经在焦点中,在全局变量中。它的任务是改变G_CORE内核中的对象属性值并重新绘制元素。它改变数值并调用Draw块。

只有三个参数需要传递给绘图块--窗口、画布和元素。它重新绘制元素,给它一个适合其当前状态的外观。绘画区块的所有辅助函数,也都使用全局变量作为焦点。例如,上述函数 "Color part() "使用 "WINDOW"、"OBJECT"、"CATEGORY_OBJECT "等。这些都是非常方便的。


现在说说缺点。

毋庸置疑,大块和焦点对象简化了代码部分之间的关系,但正是因为大块的事实,在处理它们时造成了困难。俄语和完全简化的语法在这里帮助我,因为我不使用OOP。

随着时间的推移,积木到了不再需要改变的地步,就会停止生长。渐渐地,他们的结构被完全记住了,与他们一起工作也简化到了极致。

当然,区块磨合本身,是一件相当漫长和痛苦的事情,但这就是调试任何机制的意义所在。

 
George Merts:

而关于OOP...

如果我有和Retag Konow 一样的记忆力 也许我会同意OOP是不必要的,建立所有这些接口、类、对象、继承系统和虚拟函数有什么意义呢?

阿列克谢正确地说--处理器对任何物体都一无所知......它甚至不知道什么是功能。这证明了任何任务不仅可以不用OOP,甚至可以不用函数来解决,只需记住返回地址,通过IP寄存器(或现在现代CPU使用的任何东西)传递控制。

我不理解Retug Konow的 立场,直到他给我看他的代码。现在一切都清楚了,我甚至可以同意他的观点,如果我设法把这一切都记在脑子里,长长的如果不打扰我的话,我怀疑按照他的方式写更合理。此外,在这种情况下,OOP真的成了 "车中的第五个轮子"。

但是,就我个人而言,我的问题是,大多数工作的细微之处--它在我脑海中滑过。例如,我总是忘记多维数组 G_CORE中的每个索引负责什么;在给定片段的每个条件中,我每次都会认真思考--它定义了什么。对我来说,分析长期状况也将是紧张的。

而有时我自己写的这种代码也很难理解。这是我的"不正确"代码的一个片段,我以同样的方式下沉(我在上面引用了它)。

这是CTradePosComponentI交易组件接口函数,它决定这个组件是否处于盈亏平衡状态。

"这段代码的 "错误 "在于,这里牺牲了可读性,而牺牲了紧凑性和可读性。因为功能包含在界面中--如果可能的话,我希望整个界面能在一个屏幕上看到。只是为了让我不必记住它提供了哪些功能,以便所有这些功能都能一次看到。如果我记住了一切--就没有必要将函数 "拉伸 "成一个字符串。因此,该功能在十几行上伸展开来--很好......然而,对我来说,重要的是所有的功能都能在界面上相互配合,而且所有的功能都能被看到。我希望看一眼界面就能立即对它提供的一系列功能有一个概念。这就是为什么--我不得不用一长行写出这些功能。然而,要理解它是完全不现实的。

最初,在写代码的时候--我一开始写这个函数的方式很不一样。以明确的方式和评论。这样我就能理解它。

像这样。

只有在所有这些都经过测试和调试之后--代码才被清除了注释,并 "拉到线上"。

但这是一个例外。我很少这样做--特别是在 "可见度 "很重要的情况下。在所有其他情况下,我写的代码既 "宽 "又缩进,并且在任何可能有 "这里是什么 "问题的地方都有注释。

否则,我很快就会忘记在哪里,做什么,为了什么。

我们的任务非常不同,所以我很难对你的解决方案说什么。我不确定这只是我的记忆,一定有别的原因。理解自己的代码无疑会提高其可记忆性。我不是说你的代码不那么有意义。我只是不知道我将如何处理你的问题。也许你的方法是正确的。我不是在评判。我个人认为这种风格的代码非常难以理解。

我想这是一个习惯问题)。

 
Реter Konow:

我们的任务非常不同,所以我很难对你的解决方案说什么。我不确定这只是我的记忆,一定有别的原因。把自己的代码弄清楚,无疑会让人更容易记住。我不是说你的代码不那么有意义。我只是不知道我将如何处理你的问题。也许你的方法是正确的。我不是在评判。我个人认为这种风格的代码非常难以理解。

可能吧,这是一个习惯问题)。


这是一个完全没有意义的对话:没有将代码归类为 "好 "或 "坏 "的标准。这就是为什么不清楚OOP的原因。

对我来说,这样的标准是代码的可行性,它表现在作者或第三方可以阅读代码并使用它进行修改,在相当长的一段时间后寻找错误.....。


在这里,上面的费多谢耶夫取代了OOP开关。这个特殊的例子,也许是不幸的,对我来说,是OOP的恶毒的证明:有100个位置开关的清晰代码被单行取代。要理解这条线路,你必须要去一个地方。这对我来说是不允许的。

上面第二个例子是乔治-梅茨的作品

当调试后,清除代码被非清除代码所取代。按照我的标准,高质量的代码(易于阅读)被我无法接受所取代。


因此,我有一个问题要问所有的OOP支持者:当应用OOP 时,程序会变得更加明显,而费多塞耶夫在开关上所举的例子是失败的,或者相反,费多塞耶夫的例子非常准确地描述了OOP,而OOP几乎总是导致可见性的丧失?

 
СанСаныч Фоменко:

1.一个完全没有意义的对话:没有任何标准可以将代码分类为 "好 "或 "坏"。这就是为什么不清楚OOP的原因。

对我来说,这样的标准是代码的FEASIBILITY,它表现在作者或第三方可以阅读代码并使用它来修改它,在相当长的一段时间后发现错误.....


2.在这里,上面的费多谢耶夫取代了OOP开关。这个特殊的例子,也许是不幸的,对我来说,是OOP恶性的证明:有100个位置开关的清晰代码被单行取代。要理解这条线路,你必须要去一个地方。这对我来说是不允许的。

上面第二个例子是由George Merts撰写的

当调试后,清除代码被非清除代码所取代。根据我的标准,高质量的代码(容易阅读)被我的不接受所取代。


3.因此,我有一个问题要问所有的OOP支持者:当应用OOP 时,程序会变得更加明显,而费多谢耶夫在开关上所举的例子是失败的,或者相反,费多谢耶夫的例子是对OOP非常准确的描述,OOP几乎总是导致可见性的丧失?


1.有一个标准。主要的标准是速度。

代码的清晰性是错误的标准。写代码不是为了让人看,而是为了工作。

2.我明白了,原来我们中的一些人还没有成熟到可以用函数来结构我们的代码。所以你进入了错误的主题,你应该解决 "单页代码与函数结构代码 "的问题。

此外,该样本不是关于结构化和清晰性/非显而易见性,而是关于消除压载代码片段。

3......你为什么不......学习工程制图?或描述性的几何学。那里都是非常直观的。

 
Dmitry Fedoseev:

代码可见性是错误的标准。写代码不是为了让人看,而是为了工作。

嗯,我不同意。

代码的可见性是一个非常重要的事情,因为清晰的代码更容易维护和修改。

这是正确的--我写了一个赤裸裸的函数,然后实际上对它进行了 "混淆",使它变得不可见和不可理解。这是个被迫的决定。在这种情况下,对我来说,使整个班级透明化更为重要。我牺牲了一个相当微不足道的功能的清晰性。当然,我们可以把这个函数的主体放在.mq5文件中,但我认为接口不应该被分成两个文件,应该在头文件.mqh中完全描述。

速度也是需要记住的,但我认为我们不应该追求 "不惜一切代价的速度"。必须有一个合理的充分性。