Programmation OOP vs programmation procédurale - page 23

 
Maxim Kuznetsov:

On dirait que vous avez manqué le bavardage :-) les modérateurs ont mis un frein aux sujets enflammés ... mais ici c'est OOP vs.

D'ailleurs, 99% du travail de @Peter Konow utilise la POO, mais il n'en est pas conscient :-) La POO n'est pas nécessairement "classe et modèle".

Et vice versa, d'ailleurs... la présence d'objets et de classes dans un programme n'est pas une indication de la POO.

C'est une pensée très intéressante. Peut-être que c'est le cas, et je ne le soupçonne pas. ))


Mais comment le savez-vous ?

 
Реter Konow:

C'est une pensée très intéressante. Peut-être que c'est le cas, et je ne le soupçonne pas. ))


Et comment le savez-vous ?

Par exemple, l'OO peut être mis en œuvre par le biais de la répartition des messages (et avec certains "plus" qui ne sont pas dans la classe/le modèle MQL),

Je n'ai pas regardé votre code et ne pourrai probablement pas le lire, mais puisque vous avez une bibliothèque GUI, je suis sûr qu'elle a sa propre (au moins une) file d'attente et que le traitement des événements/envois/états permet de tout regrouper. Et cette même "torsion" n'est finalement que de l'héritage/polymorphisme.

 
Dmitry Fedoseev:

A propos du hérisson :

" Le hérisson se tient dans la clairière, il prend la pose, il fait jouer ses biceps : - Je suis fort, je suis courageux, je suis agile, je suis fort, je suis courageux, je suis agile...

Un ours passe par là - lui donne un coup de pied, le hérisson s'envole derrière l'arbre, se relève et se secoue :

- Je suis fort, je suis courageux, je suis agile... ...mais je suis léger...


Comme le disait mon ami d'enfance, le hérisson est un oiseau fier, si vous ne lui donnez pas de coup de pied, il ne volera pas ;))
 
Alexey Volchanskiy:

Georges, j'ai fait une petite promenade avec une fille aujourd'hui, on a discuté un peu, on s'est souvenu des hommes timides. Honnêtement, je ne me moque pas, chacun a une personnalité différente et une éducation différente.

Oh... Et Lekha est pour les poussins... Et à juste titre. Bien plus intéressant que le GOP.

Eh bien, mon problème n'est pas la timidité. C'est la "langue bien pendue" qui est la seule chose dont je puisse me vanter. Mon problème, c'est le vaginocentrisme avec le manque d'argent. J'accorde trop de valeur à la vie privée et au sexe. Vous avez écrit plus haut : "... j'ai vu à quel point les hommes peuvent travailler dur quand de belles femmes les attendent." Eh bien, je suis l'un de ces gars-là. Sauf que, les filles, elles ont besoin de toi tant que tu es jeune, fort et riche. Et si une nana a une chance de te baiser, elle va forcément te baiser tôt ou tard. Même un jeune, fort et riche. Je suis un vieil invalide sans le sou et sans maison. Donc mes chances sont nulles... Je ne suis même pas surpris que ma femme soit partie. Seulement vous ne semblez pas vous soucier du fait que vous êtes divorcé. Pour ma part, je trouve extrêmement frustrant de ne pas avoir pu créer les conditions nécessaires pour que ma femme ne puisse pas partir.

 

Et à propos de OOP...

Si j'avais la même mémoire que Retag Konow, je serais peut-être d'accord pour dire que la POO est inutile, à quoi bon construire toutes ces interfaces, classes, objets, système d'héritage et fonctions virtuelles...

Alexey a dit correctement - le processeur ne sait rien sur aucun objet... Il ne connaît même pas les fonctions. Ce qui prouve que n'importe quelle tâche peut être résolue non seulement sans POO mais même sans fonctions, simplement en se souvenant des adresses de retour et en passant le contrôle via le registre IP (ou ce que les CPU modernes utilisent de nos jours).

Je n'ai pas compris la position de Retug Konow jusqu'à ce qu'il me montre son code. Maintenant tout est clair et je peux même être d'accord avec lui, si j'arrive à garder tout en mémoire et que les longs "si" ne me dérangent pas, je soupçonne qu'il est plus raisonnable de l'écrire comme il le fait. De plus, dans ce cas, la POO devient vraiment une "cinquième roue du chariot".

Mais, personnellement, mon problème est que la plupart des subtilités du travail - cela m'échappe. Par exemple, j'oublierai toujours à quoi sert chaque indice du tableau multidimensionnel G_CORE ; dans chaque condition d'un fragment donné, je réfléchirai chaque fois sérieusement à ce qu'il définit. L'analyse des conditions longues sera également tendue pour moi.

Et parfois, j'écris moi-même un tel code qui est difficile à comprendre. Voici un fragment de MON code"incorrect" où je m'enfonce de la même manière (je l'ai cité ci-dessus) :

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

Il s'agit de la fonction de l'interface du composant de négociation CTradePosComponentI, qui détermine si ce composant est au seuil de rentabilité.

"La "faute" de ce code est que la lisibilité est sacrifiée ici au détriment de la compacité et de la lisibilité. Comme la fonction est incluse dans l'interface, je voulais que toute l'interface soit visible sur un seul écran, si possible. Pour que je n'aie pas à me souvenir des fonctions qu'il offre, pour que toutes ces fonctions puissent être vues en même temps. Si je me souvenais de tout - il n'y aurait pas besoin d'"étirer" la fonction en une chaîne de caractères. Donc la fonction s'est étendue sur une douzaine de lignes - bien... Cependant, il était important pour moi que toutes les fonctions s'intègrent dans l'interface les unes à côté des autres, et qu'elles soient toutes visibles. Je voulais qu'un seul coup d'œil à l'interface me donne instantanément une idée de l'ensemble des fonctions qu'elle offre. C'est pourquoi - j'ai dû écrire les fonctions en une seule longue ligne. Cependant, il est totalement irréaliste de le comprendre.

Au départ, lors de l'écriture du code - j'ai d'abord écrit cette fonction de manière assez différente. De manière claire et avec des commentaires. Pour que je puisse le comprendre.

Comme ça :

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

Et ce n'est qu'après avoir été testé et débogué que le code a été débarrassé des commentaires et "mis en ligne".

Mais c'est une exception. Je le fais très rarement, dans des cas particuliers où la "visibilité" est importante. Dans tous les autres cas - j'écris du code à la fois "large" et avec indentation, et avec des commentaires à n'importe quel endroit, où il pourrait y avoir le moindre problème avec une question "qu'est-ce qu'il y a ici".

Sinon, j'oublie très vite où, quoi et à quoi ça sert.

 
Maxim Kuznetsov:

Par exemple, l'OO est tout à fait réalisable par le biais de la répartition des messages (et avec quelques "plus" qui ne sont pas dans la classe/le modèle MQL),

Je n'ai pas regardé votre code et je ne peux pas le lire, mais puisque vous avez une bibliothèque GUI, je suis sûr qu'elle a sa propre (au moins une) file d'attente et par le traitement des événements/sentences/états il y a beaucoup de choses qui sont foutues. Et cette même "torsion" n'est finalement que de l'héritage/polymorphisme.

Eh bien, maintenant que j'ai dit "A", je dois dire "B" aussi). Je vais décrire plus précisément ma technologie.

En combinant les fonctionnalités travaillant sur un type particulier de tâches en de grands blocs, je réduis le nombre de liens qui doivent être construits entre les fonctions. Cela a ses avantages et ses inconvénients.

Tout d'abord, les avantages :

En POO, un mécanisme décomposé en un grand nombre de fonctions, nécessite la création de nombreux objets pour faire le lien entre les classes et les structures. En même temps, chaque prototype de fonction est entouré d'un grand nombre de paramètres formels, par lesquels la fonction communique avec le code environnant. La structure interne du code devient plus complexe précisément en raison de l'augmentation des liens entre les parties du mécanisme au cours du développement de ce dernier.

Dans ma technologie, la communication entre les fonctions et les blocs est entièrement simplifiée par l'utilisation de variables globales, qui sont estampillées partout. Les fonctions n'ont pas besoin de passer des paramètres car elles les voient immédiatement au niveau global.

Lesvaleurs des variables globales sont définies par le bloc Object Focus, qui "suit" le curseur. Il utilise les coordonnées actuelles du curseur pour déterminer sur quel objet se trouve la souris et accède au noyau (G_CORE) qui stocke toutes les propriétés de tous les éléments, objets et fenêtres. À partir du noyau, le bloc prend les valeurs actuelles de toutes les propriétés principales de l'objet situé sous le curseur et les place dans les variables globales. Si le curseur se déplace sur les objets, les variables globales sont redéfinies dans ce bloc et correspondent toujours à l'objet qui est en focus.

Ensuite, la fonction OnChartEvent() capture les événements graphiques qui doivent modifier l'état de l'élément situé sous le curseur. Lors de ces événements, le bloc de contrôle d'état (qui est intégré dans la fonction OnChartEvent() elle-même) voit immédiatement quelle fenêtre, quel élément et quel objet sont en focus et quelles sont leurs propriétés. Vous n'avez pas besoin de passer quoi que ce soit à ce bloc, car tout ce dont vous avez besoin se trouve déjà dans le focus, dans les variables globales. Sa tâche consiste à modifier les valeurs des propriétés de l'objet dans le noyau G_CORE et à redessiner l'élément. Il modifie les valeurs et appelle le bloc Draw.

Seuls trois paramètres doivent être transmis au bloc de dessin : la fenêtre, le canevas et l'élément. Il redessine l'élément, lui donnant une apparence appropriée à son état actuel. Toutes les fonctions auxiliaires du bloc peinture, utilisent également des variables globales en focus. Par exemple, la fonction ci-dessus "Color part()" utilise "WINDOW", "OBJECT", "CATEGORY_OBJECT" etc... Tout cela est très pratique.


Maintenant, les inconvénients :

Il ne fait aucun doute que les grands blocs et les objets focus simplifient la relation entre les parties du code, mais le fait que les blocs soient grands crée des difficultés lorsqu'on travaille avec eux. La langue russe et la simplification totale de la syntaxe m'aident ici, puisque je n'utilise pas la POO.

Avec le temps, les blocs arrivent à un point où ils n'ont plus besoin d'être modifiés et cessent de croître. Petit à petit, leur structure est entièrement mémorisée et le travail avec eux est simplifié au maximum.

Bien sûr, le broyage des blocs en lui-même est une chose plutôt longue et pénible, mais c'est ce qui fait le débogage de tout mécanisme.

 
George Merts:

Et à propos de OOP...

Si j'avais la même mémoire que Retag Konow, je serais peut-être d'accord pour dire que la POO est inutile, à quoi bon construire toutes ces interfaces, classes, objets, système d'héritage et fonctions virtuelles...

Alexey a dit correctement - le processeur ne sait rien sur aucun objet... Il ne connaît même pas les fonctions. Ce qui prouve que n'importe quelle tâche peut être résolue non seulement sans POO, mais même sans fonctions, simplement en se souvenant des adresses de retour et en passant le contrôle via le registre IP (ou ce que les CPU modernes utilisent de nos jours).

Je n'ai pas compris la position de Retug Konow jusqu'à ce qu'il me montre son code. Maintenant tout est clair et je peux même être d'accord avec lui, si j'arrive à garder tout en mémoire et que les longs "si" ne me dérangent pas, je soupçonne qu'il est plus raisonnable de l'écrire comme il le fait. De plus, dans ce cas, la POO devient vraiment une "cinquième roue du chariot".

Mais, personnellement, mon problème est que la plupart des subtilités du travail - cela m'échappe. Par exemple, j'oublierai toujours à quoi sert chaque indice du tableau multidimensionnel G_CORE ; dans chaque condition d'un fragment donné, je réfléchirai chaque fois sérieusement à ce qu'il définit. L'analyse des conditions longues sera également tendue pour moi.

Et parfois, j'écris moi-même un tel code qui est difficile à comprendre. Voici un fragment de MON code"incorrect" où je m'enfonce de la même manière (je l'ai cité ci-dessus) :

Il s'agit de la fonction de l'interface du composant de négociation CTradePosComponentI, qui détermine si ce composant est au seuil de rentabilité.

"La "faute" de ce code est que la lisibilité est sacrifiée ici au détriment de la compacité et de la lisibilité. Comme la fonction est incluse dans l'interface, je voulais que toute l'interface soit visible sur un seul écran, si possible. Pour que je n'aie pas à me souvenir des fonctions qu'il offre, pour que toutes ces fonctions puissent être vues en même temps. Si je me souvenais de tout - il n'y aurait pas besoin d'"étirer" la fonction en une chaîne de caractères. Donc la fonction s'est étendue sur une douzaine de lignes - bien... Cependant, il était important pour moi que toutes les fonctions s'intègrent dans l'interface les unes à côté des autres, et qu'elles soient toutes visibles. Je voulais qu'un simple coup d'œil à l'interface me donne instantanément une idée de l'ensemble des fonctions qu'elle propose. C'est pourquoi - j'ai dû écrire les fonctions en une seule longue ligne. Cependant, il est totalement irréaliste de le comprendre.

Au départ, lors de l'écriture du code - j'ai d'abord écrit cette fonction de manière assez différente. De manière claire et avec des commentaires. Pour que je puisse le comprendre.

Comme ça :

Et ce n'est qu'après avoir été testé et débogué que le code a été débarrassé de ses commentaires et "tiré à la ligne".

Mais c'est une exception. Je procède de cette façon très rarement - dans les cas particuliers où la "visibilité" est importante. Dans tous les autres cas, j'écris du code à la fois "large" et indenté, et avec des commentaires à tout endroit où il pourrait y avoir le moindre accroc d'une question "qu'est-ce qu'il y a ici".

Sinon, j'oublie très vite où, quoi et pour quoi...

Nos tâches sont très différentes, il m'est donc difficile de me prononcer sur vos solutions. Je ne suis pas sûr que ce soit juste ma mémoire, il doit y avoir autre chose. Donner un sens à votre propre code améliore sans aucun doute sa mémorisation. Je ne dis pas que votre code est moins significatif. Je ne sais pas comment j'aborderais vos problèmes. Peut-être que votre approche est la bonne. Je ne juge pas. Personnellement, je trouve ce style de code très difficile à comprendre.

Je suppose que c'est une question d'habitude).

 
Реter Konow:

Nos tâches sont très différentes, il m'est donc difficile de me prononcer sur vos solutions. Je ne suis pas sûr que ce soit juste ma mémoire, il doit y avoir autre chose. Donner un sens à son propre code le rend incontestablement plus facile à mémoriser. Je ne dis pas que votre code est moins significatif. Je ne sais pas comment j'aborderais vos problèmes. Peut-être que votre approche est la bonne. Je ne juge pas. Personnellement, je trouve ce style de code très difficile à accepter.

C'est probablement une question d'habitude).


C'est uneconversation totalement insensée : il n'existe aucun critère permettant de classer un code comme "bon" ou "mauvais". C'est pourquoi il n'est pas clair sur la POO.

Pour moi, ce critère est la FAISABILITÉ du code, qui se manifeste par le fait que l'auteur ou un tiers peut lire le code et l'utiliser pour le modifier, en recherchant les bogues après une assez longue période de temps......


Ici, au-dessus, Fedoseyev a remplacé l'interrupteur OOP. Cet exemple particulier, peut-être malheureux, est pour moi une preuve de la méchanceté de la POO : un code clair avec un interrupteur à 100 positions est remplacé par une seule ligne. Pour comprendre cette ligne, il faut aller quelque part. Ce n'est pas admissible pour moi.

Le deuxième exemple ci-dessuspar George Merts

Lorsque le code clair a été remplacé par un code NON clair après le débogage. Selon mon critère, le code de qualité (facile à lire) a été remplacé par le code qui n'est pas acceptable pour moi.


J'ai donc une question à poser à tous les partisans de la POO : le programme devient-il plus visible lorsque la POO est appliquée et l'exemple donné par Fedoseev sur le commutateur est un échec ou au contraire, l'exemple de Fedoseev caractérise très précisément la POO et la POO conduit presque toujours à une perte de visibilité ?

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

1. Une conversation totalement inutile : il n'existe aucun critère permettant de classer un code comme "bon" ou "mauvais". C'est pourquoi il n'est pas clair sur la POO.

Pour moi, ce critère est la FAISABILITÉ du code, qui se manifeste par le fait que l'auteur ou un tiers peut lire le code et l'utiliser pour le modifier, trouver des bugs après une période de temps assez longue......


2. Ici, au-dessus, Fedoseyev a remplacé l'interrupteur OOP. Cet exemple particulier, peut-être malheureux, est pour moi une preuve de la méchanceté de la POO : un code clair avec un interrupteur à 100 positions est remplacé par une seule ligne. Pour comprendre cette ligne, il faut aller quelque part. Ce n'est pas admissible pour moi.

Le deuxième exemple ci-dessuspar George Merts

Lorsque le code clair a été remplacé par un code NON clair après le débogage. Selon mon critère, le code de qualité (facile à lire) a été remplacé par un code inacceptable pour moi.


3. J'ai donc une question pour tous les partisans de la POO : est-ce que le programme devient plus visible lorsque la POO est appliquée et l'exemple donné par Fedoseyev sur le commutateur est un échec, ou au contraire, l'exemple de Fedoseyev est une description très précise de la POO et la POO conduit presque toujours à une perte de visibilité ?


1. Il existe un critère. Le principal critère est la vitesse.

La clarté du code n'est pas le bon critère. Le code est écrit non pas pour être regardé mais pour fonctionner.

2. Je vois, il s'avère que certains d'entre nous ne sont pas assez matures pour structurer leur code avec des fonctions. Vous êtes donc dans le mauvais sujet, vous devriez aborder le sujet "code d'une page vs. code structuré en fonctions".

De plus, l'échantillon ne portait pas sur la structuration et la clarté/non-évidence mais sur l'élimination de fragments de code de lest.

3... pourquoi ne pas... Se lancer dans l'ingénierie graphique ? Ou la géométrie descriptive. C'est très visuel.

 
Dmitry Fedoseev:

La visibilité du code n'est pas le bon critère. Le code n'est pas écrit pour être regardé, mais pour fonctionner.

Eh bien, je ne suis pas d'accord.

La visibilité du code est une chose très importante car un code clair est beaucoup plus facile à maintenir et à modifier.

C'est vrai - j'ai écrit une fonction nue et je l'ai ensuite "obscurcie", rendue non visible et incompréhensible. C'était une décision forcée. Dans ce cas, il était plus important pour moi de rendre la classe entière transparente. J'ai sacrifié la clarté d'une fonction tout à fait triviale. Bien sûr, nous aurions pu mettre le corps de cette fonction dans le fichier .mq5, mais je pense que les interfaces ne devraient pas être divisées en deux fichiers et devraient être complètement décrites dans le fichier d'en-tête .mqh.

La vitesse est également un élément à prendre en compte, mais je ne pense pas qu'il faille rechercher la "vitesse à tout prix". Il doit y avoir une suffisance raisonnable.

Raison: