OOP vs procedural programming - page 23

 
Maxim Kuznetsov:

Looks like you missed the chatter :-) the moderators have clamped down on flaming topics ... but here it's OOP vs.

By the way, 99% of @Peter Konow's uses OOP, but he's not aware of it :-) OOP is not necessarily "class & template".

And vice versa by the way...the presence of objects and classes in a program is not indicative of OOP

That's a very interesting thought. Perhaps it is, and I don't suspect it. ))


But how do you know it?

 
Реter Konow:

That's a very interesting thought. Perhaps it is, and I don't suspect it is. ))


And how do you know about it?

For example, the OO can be implemented through message dispatching (and with some "pluses" that are not in the class/template MQL),

I haven't looked through your code and probably won't be able to read it, but since you're using GUI library, I'm sure it has at least one queue and events/sentence/states processing has a lot of twists. And this very "twisting" in the end is just inheritance/polymorphism.

 
Dmitry Fedoseev:

About the hedgehog:

"The hedgehog stands in the clearing, posing, flexing his biceps: - I'm strong, I'm brave, I'm agile, I'm strong, I'm brave, I'm agile...

A bear walks by - kicks him once, the hedgehog flies behind the tree, gets up and shakes himself off:

- I'm strong, I'm brave, I'm agile... ...but I'm light...


As my childhood friend used to say, the hedgehog is a proud bird, if you don't kick it, it won't fly ))
 
Alexey Volchanskiy:

Georges, I went for a little walk with a girl today, we chatted a bit, we remembered a bit about shy men. Honestly, I don't poke fun, everyone has different personalities and different upbringing.

Oh... And Lekha's for chicks... And rightly so. Much more interesting than the GOP.

Well, my problem isn't shyness. It's the "well-hung tongue" that's the only thing I can boast about. My problem is vaginocentrism with pennilessness. I place too much value on privacy and sex. You wrote above, "...I've seen how hard guys can work when beautiful women loom ahead." Well, I'm one of those guys. Except, chicks, they need you while you're young and strong and rich. And if a chick has a chance to fuck you over, she's bound to fuck you over sooner or later. Even a young, strong and rich one. I'm a penniless old invalid with no home. So my chances are nil... I'm not even surprised my wife left. Only you don't seem to care that you're divorced. I, on the other hand, find it extremely frustrating that I couldn't create the conditions where my wife couldn't leave.

 

And about OOP...

If I had the same memory as Retag Konow, maybe I would agree that OOP is unnecessary, what's the point of building all these interfaces, classes, objects, inheritance system and virtual functions...

Alexey correctly said - processor doesn't know anything about any objects... It doesn't even know anything about functions. Which proves that any task can be solved not only without OOP but even without functions, just by remembering return addresses and passing control via IP register (or whatever modern CPUs use nowadays).

I didn't understand Retug Konow' s position until he showed me his code. Now everything is clear and I can even agree with him, if I manage to keep it all in memory and long if's don't bother me, I suspect that it's more reasonable to write it the way he does. Moreover, in this case OOP really becomes a "fifth wheel in the cart".

But, personally, my problem is that most of subtleties of work - it slips my mind. For example, I'll always forget what each index in multidimensional array G_CORE is responsible for; in each condition in given fragment - I'll every time seriously think over - what it defines. Analysis of long conditions will also be tense for me.

And sometimes I myself write such code which is difficult to understand. Here's a fragment of MY"incorrect" code where I'm sinking in the same way (I've cited it above):

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); };

This is the CTradePosComponentI trading component interface function, which determines whether this component is at breakeven.

"The "wrongness" of this code is that readability is sacrificed here at the expense of compactness and readability. Because the function is included in the interface - I wanted the whole interface to be visible on one screen, if possible. Just so I don't have to remember what features it provides, so that all those features can be seen at once. If I remembered everything - there would be no need to "stretch" the function into a string. So the function stretched out on a dozen lines - fine... However, it was important to me that all of the functions would fit in the interface next to each other, and all of them would be visible. I wanted one glance at the interface to instantly give me an idea of the set of functions it provides. This is why - I had to write out the functions in one long line. However, it's totally unrealistic to understand it.

Initially, when writing the code - I wrote this function quite differently at first. In a clear way and with comments. So that I could understand it.

Like this:

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); 
};

And only after all this was tested and debugged - the code was cleared of comments and "pulled into line".

But this is an exception. I do this very rarely, in special cases when "visibility" is important. In all other cases - I write code both "wide" and with indentation, and with comments in any place, where there could be the slightest hitch with a question "what's here".

Otherwise, I forget very quickly where, what and for what.

 
Maxim Kuznetsov:

For example, OO is quite feasible through message dispatch (and with some "pluses" that are not in the class/template MQL),

I haven't looked through your code and can't read it, but since you have GUI library, I'm sure it has its own (at least one) queue and through processing of events/sentences/states there are many things screwed up. And this very "twisting" in the end is just inheritance/polymorphism.

Well, now that I've said "A", I'd like to say "B", too). I will describe my technology more specifically.

By combining the functionality working on a particular type of tasks into large blocks, I reduce the number of links that need to be built between the functions. This has its pros and cons.

First about the pros:

In OOP, a mechanism broken down into a large number of functions, requires creation of many objects to link between the classes and the structures. At the same time, each function prototype is surrounded by a large number of formal parameters, through which the function communicates with the surrounding code. The internal structure of the code becomes more complex precisely because of the increase in the links between the parts of the mechanism during the development of this mechanism.

In my technology, communication between functions and blocks is simplified entirely through the use of global variables, which are stamped throughout. Functions do not need to pass parameters because they see them immediately at the global level.

Global variable values are set by the Object Focus block, which "tracks" the cursor. It uses the current coordinates of the cursor to determine which object the mouse is on and accesses the kernel (G_CORE) that stores all the properties of all elements, objects and windows. From the kernel, the block takes the current values of all the main properties of the object under the cursor and places them in the global variables. If the cursor moves over the objects, the global variables are redefined in this block and always correspond to the object that is in focus.

Next, the OnChartEvent() function captures chart events that should change the state of the element under the cursor. On these events, the state control block (which is integrated into OnChartEvent() itself) immediately sees which window, element and object are in focus and what their properties are. You don't need to pass anything to this block, because everything you need is already in focus, in global variables. Its task is to change values of object properties in G_CORE kernel and redraw the element. It changes the values and calls the Draw block.

Only three parameters need to be passed to the drawing block - window, canvas and element. It redraws the element, giving it an appearance appropriate to its current state. All auxiliary functions of the painting block, also use global variables in focus. For example, the above function "Color part()" uses "WINDOW", "OBJECT", "CATEGORY_OBJECT" etc... These are all very handy.


Now for the cons:

Undoubtedly, large blocks and focus objects simplify the relationship between code parts, but it is because of the fact that the blocks are large, creating difficulties when working with them. The Russian language and total simplification of syntax help me here, since I don't use OOP.

Over time, blocks get to the point where they no longer need to be changed and stop growing. Gradually their structure is fully memorized and working with them is simplified to the max.

Of course, block grinding itself, is a rather long and painful thing, but that's what debugging any mechanism is all about.

 
George Merts:

And about OOP...

If I had the same memory as Retag Konow, maybe I would agree that OOP is unnecessary, what's the point of building all these interfaces, classes, objects, inheritance system and virtual functions...

Alexey correctly said - processor doesn't know anything about any objects... It doesn't even know anything about functions. Which proves that any task can be solved not only without OOP but even without functions, just by remembering return addresses and passing control via IP register (or whatever modern CPUs use nowadays).

I didn't understand Retug Konow' s position until he showed me his code. Now everything is clear and I can even agree with him, if I manage to keep it all in memory and long if's don't bother me, I suspect that it's more reasonable to write it the way he does. Moreover, in this case OOP really becomes a "fifth wheel in the cart".

But, personally, my problem is that most of subtleties of work - it slips my mind. For example, I'll always forget what each index in multidimensional array G_CORE is responsible for; in each condition in given fragment - I'll every time seriously think over - what it defines. Analysis of long conditions will also be tense for me.

And sometimes I myself write such code which is difficult to understand. Here's a fragment of MY"incorrect" code where I'm sinking in the same way (I've cited it above):

This is the CTradePosComponentI trading component interface function, which determines whether this component is at breakeven.

"The "wrongness" of this code is that readability is sacrificed here at the expense of compactness and readability. Because the function is included in the interface - I wanted the whole interface to be visible on one screen, if possible. Just so I don't have to remember what features it provides, so that all those features can be seen at once. If I remembered everything - there would be no need to "stretch" the function into a string. So the function stretched out on a dozen lines - fine... However, it was important to me that all of the functions would fit in the interface next to each other, and all of them would be visible. I wanted one glance at the interface to instantly give me an idea of the set of functions it provides. This is why - I had to write out the functions in one long line. However, it's totally unrealistic to understand it.

Initially, when writing the code - I wrote this function quite differently at first. In a clear way and with comments. So that I could understand it.

Like this:

And only after all this had been tested and debugged - was the code cleared of comments and "pulled to the line".

But this is an exception. I do this way very rarely - in particular cases when "visibility" is important. In all other cases I write code both "wide" and indented, and with comments in any place where there could be the slightest hitch of a question "what's here".

Otherwise, I forget very quickly where, what and what it's for

Our tasks are very different, so it's hard for me to say anything about your solutions. I'm not sure it's just my memory, there must be something else. Making sense of your own code undoubtedly improves its memorability. I'm not saying your code is less meaningful. I just don't know how I would approach your problems. Maybe your approach is the right one. I'm not judging. Personally I find this style of code very hard to comprehend.

I guess it's a matter of habit.)

 
Реter Konow:

Our tasks are very different, so it's hard for me to say anything about your solutions. I'm not sure it's just my memory, there must be something else. Making sense of your own code undoubtedly makes it easier to remember. I'm not saying your code is less meaningful. I just don't know how I would approach your problems. Maybe your approach is the right one. I'm not judging. Personally I find this style of code very difficult to understand.

Probably, it's a matter of habit.)


It's a completely senseless conversation: there is no criterion of categorizing code as "good" or "bad". That's why it's not clear about OOP.

For me such criterion is the FEASIBILITY of code, which manifests itself in the fact that the author or a third party can read the code and use it for modification, searching for bugs after quite a long period of time.....


Here above Fedoseyev has replaced the OOP switch. This particular example, maybe unfortunate, to me is a proof of the viciousness of OOP: clear code with a 100 position switch is replaced by a single line. To understand this line you have to go somewhere. It's not permissible for me.

The second example aboveby George Merts

When the clear code was replaced by NOT clear code after debugging. By my criterion quality code (easy to read) was replaced by unacceptable for me.


So I have a question to all the OOP supporters: does the program becomes more visible when OOP is applied and the example given by Fedoseev on the switch is a failure or on the contrary, Fedoseev's example very accurately characterizes OOP and OOP almost always leads to a loss of visibility?

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

1. A completely pointless conversation: there is no criterion for classifying code as "good" or "bad". That is why it is not clear about OOP.

For me, such criterion is the FEASIBILITY of the code, which manifests itself in the fact that the author or a third party can read the code and use it to modify it, find bugs after a fairly long period of time.....


2. Here above Fedoseyev has replaced the OOP switch. This particular example, maybe unfortunate, to me is a proof of viciousness of OOP: clear code with a 100-position switch is replaced by a single line. To understand this line you have to go somewhere. It's not permissible for me.

The second example aboveby George Merts

When the clear code was replaced by NOT clear code after debugging. By my criterion the quality code (easy to read) was replaced by unacceptable for me.


3. So I have a question for all the OOP supporters: does the program becomes more visible when OOP is applied and the example given by Fedoseyev on the switch is a failure, or on the contrary, Fedoseyev's example is a very accurate description of OOP and OOP almost always leads to a loss of visibility?


1. There is a criterion. The main criterion is speed.

The code's clarity is the wrong criterion. The code is written not to be looked at but to work.

2. I see, it turns out that some of us are not mature enough to structure our code with functions. So you are in the wrong topic, you should address the topic "one-page code vs. function-structured code".

Besides, the sample was not about structuring and clearness/non-obviousness but about eliminating ballast code fragments.

3... why don't you... Take up engineering graphics? Or descriptive geometry. It's all very visual there.

 
Dmitry Fedoseev:

Code visibility is the wrong criterion. Code is not written to be looked at, but to work.

Well, I disagree.

Code visibility is a very important thing because clear code is much easier to maintain and modify.

That's right - I wrote a naked function and then actually "obfuscated" it, made it non-visible and incomprehensible. This was a forced decision. In this case, it was more important to me to make the entire class transparent. I have sacrificed the clarity of one quite trivial function. Of course, we could have put the body of this function in .mq5 file, but I believe that interfaces should not be divided into two files and should be completely described in the .mqh header file.

Speed is also something to keep in mind, but I don't think we should strive for "speed at all costs". There has to be a reasonable sufficiency.