Frais généraux de l'OLP - page 3

 
George Merts:

1. Par exemple, vous avez besoin d'un tableau d'objets.

Vous pouvez le faire de manière procédurale ou en vous basant sur CArrayObj et CObjest. Les problèmes commencent lorsque vous devez modifier le comportement, par exemple, en ajoutant ou en supprimant des objets, ou en les triant. Dans la POO, le support d'un tableau de pointeurs proprement dit et son utilisation sont inclus dans les objets de base. La modification des objets descendants qui sont effectivement contenus dans le tableau n'a aucune incidence. En style procédural - modifier des objets réels qui sont en fait contenus dans un tableau - affecte généralement beaucoup plus d'endroits, au moins parce que nous devons tenir compte des changements de taille des objets. Ce qui entraînera beaucoup plus facilement des erreurs.

2. Multiplateforme - également beaucoup plus pratique à organiser dans le style OOP. Lorsque nous demandons, par exemple, une position commerciale, nous obtenons une interface, et peu importe la plateforme sur laquelle nous travaillons - l'interface offre des fonctions virtuelles, sur lesquelles vous pouvez obtenir toutes les données sur tous les ordres (pour MT4) ou les positions (MT5), et, du point de vue de l'expert - il n'y a aucune différence. Le conseiller expert n'a pas besoin de savoir sur quelle plateforme il travaille.

3) Eh bien, "finir en programmation procédurale", c'est "écrire des objets-procédures", c'est-à-dire la création de certains liens entre les données et les procédures, qui représentent les objets dans la POO.

4. et puis nous avons, disons, un certain nombre de types d'ordres, qui ont beaucoup en commun. Il serait raisonnable de créer un objet COrderInfo - qui serait l'objet de base, et ses héritiers représenteraient différents types d'ordres. À ce moment-là, le processeur de transaction (j'ai la classe CTradeProcessor) prendra automatiquement en charge précisément cet ordre, qui lui a été transmis, par les procédures nécessaires au traitement de cet ordre.

5. il est plus facile d'attraper les insectes là où il y a le moins de liens croisés. Ceci est assuré par l'encapsulation et le polymorphisme. Nous demandons l'interface de la position commerciale (CTradePositionI) et toutes les connexions avec les classes réelles, représentant cette position (CMT4PositionInfo,CMT5PositionInfo) sont faites uniquement à travers cette interface, ce qui contribue simplement à une correction d'erreur plus facile, que si nous travaillons directement avec les fonctions réelles, retournant les données de la position commerciale.

1. Pour quoi faire ?

Pourquoi la même fonction ne peut-elle pas être compilée sur différentes plateformes ?

3. l'idée était d'emballer le texte des fonctions par le type de structure pour qu'il soit plus pratique de s'y référer par analogie avec la référence à une fonction comme membre de classe. En principe, aucun objet ne doit être créé à cette fin.

4. Il serait plus raisonnable de faire une seule fonction avec ses paramètres, plutôt que de multiplier plusieurs objets et des connexions inutiles à travers des interfaces.

5. En outre, tous ces liens doivent être programmés, puis suivis à travers les interfaces et autres, où les bogues peuvent être difficiles à attraper. Cette occupation est inutile et insensée depuis le tout début.

 
Andrei:

1. Par exemple, pour quoi faire ?

2) Pourquoi la même fonction ne peut-elle pas être compilée sur différentes plates-formes, de sorte qu'il ne soit pas nécessaire de créer des interfaces pour elle ?

Je voulais dire regrouper le texte des fonctions en fonction du type de structure pour un accès plus pratique, comme si on adressait une fonction comme un membre de classe. En principe, aucun objet ne doit être créé à cette fin.

4. Il est plus intelligent de faire une seule fonction avec des paramètres, au lieu de multiplier plusieurs objets et des connexions inutiles à travers des interfaces.

5. En outre, tous ces liens doivent être programmés, puis suivis à travers les interfaces et autres, où les bogues peuvent être difficiles à attraper. Cette occupation est inutile et insensée depuis le tout début.

1. Eh bien, la classe CTradePosition est essentiellement une liste d'ordres ouverts. Et pour eux, il serait très utile d'avoir une interface, une classe de base et des classes réelles.

2. Il n'y a qu'une seule interface. Pour toutes les plateformes. Et dans le cas de la POO, nous ne pensons pas vraiment à l'endroit où nous travaillons. Nous n'avons pas à tenir compte des éléments qui dépendent de la plate-forme et de l'ordre.

Et quelle est la différence entre objet et fonction dans cet emballage ? C'est ce que je dis - c'est essentiellement la même chose. Dans le cas d'un objet, une fonction de constructeur automatique est également ajoutée, mais par défaut, elle est vide.

4. Exactement, cette même "fonction unique avec des paramètres" est la source des problèmes. Parce qu'il y a généralement beaucoup de paramètres. Et ils ne sont pas dispersés à différents niveaux de la hiérarchie des classes, mais concentrés dans cette même fonction. C'est exactement le principal avantage de la POO - toutes les fonctionnalités sont "dispersées" dans des objets à différents niveaux de la hiérarchie et lorsque l'on travaille avec telle ou telle partie de ces objets, les autres n'interfèrent pas. Dans une fonction unique avec des paramètres, en revanche, toutes les fonctionnalités sont toujours disponibles, même si elles sont superflues. C'est généralement une source de problèmes, simplement parce que vous pouvez accidentellement mélanger les variables. Le principal inconvénient est qu'il est beaucoup plus difficile de détecter les erreurs dans une telle fonction unique.

5. dans tous les cas, ces liens sont nécessaires et doivent être programmés - il s'agit en fait des mêmes réglages dans une seule fonction. Par exemple, dans mon exemple - dans une seule fonction, nous avons accès à la différence des plateformes, aux différents types d'ordres, à la différence de représentation des positions - tout cela doit être pris en compte. Et lorsqu'il y a une interface - tout est "coupé" - seul ce qui est défini dans l'interface peut être pris en compte.

C'est le but de l'encapsulation, limiter l'accès d'un bloc de code à un autre bloc. Au contraire, vous suggérez d'avoir "une grande fonction universelle avec un maximum de paramètres", de sorte que toute personne ayant accès à cette fonction ait un maximum de possibilités. Comme le montre mon expérience, ce n'est pas la bonne méthode. La bonne méthode consiste au contraire à limiter l'utilisateur autant que possible : si un bloc du programme a besoin de la fonctionnalité d'un autre bloc, il ne doit avoir que cette fonctionnalité, et pas une de plus. C'est la clé d'un code plus stable et sans erreur.

 
George Merts:

1. Eh bien, la classe CTradePosition est essentiellement une liste d'ordres ouverts. Les commandes peuvent être différentes, et pour elles il est très pratique d'avoir une interface, une classe de base, et des classes réelles.

Et qu'y a-t-il de mal à conserver les ordres dans un tableau de structures, ou de la manière dont cela est implémenté dans MT4 ?

 
Andrei:

Qu'y a-t-il de mal à conserver les ordres dans un tableau de structures ou tel qu'implémenté dans MT4 ?

Parce que chaque utilisateur a trop de droits et trop d'informations inutiles lorsqu'il accède à ce tableau.

La bonne chose à faire, à mon avis, est de ne donner à l'utilisateur que la partie de la fonctionnalité dont il a besoin - en utilisant simplement une interface préétablie pour accéder aux commandes.

 
George Merts:

Que chaque utilisateur a trop de droits et trop d'informations inutiles lorsqu'il accède à ce tableau.

La bonne chose à faire, à mon avis, est de ne donner à l'utilisateur que la partie de la fonctionnalité dont il a besoin - en utilisant simplement une interface convenue à l'avance pour accéder aux commandes.

Vous pouvez créer votre propre type de données pour les ordres, il n'y a pas besoin d'interface, d'objets et autres artifices inutiles, qui créent des bogues et des instabilités inutiles.

 
Andrei:

Vous pouvez créer votre propre type de données pour les ordres, il n'y a pas besoin d'interface, d'objets et autres artifices inutiles, qui créent des bogues et des instabilités inutiles.

Mon expérience montre que vous en avez besoin.

J'ai suivi cette voie il y a environ cinq ans, à l'époque sur MT4. (Non pas parce que je ne connaissais pas la POO, mais parce que j'étais trop paresseux pour me préoccuper des interfaces et de l'héritage, d'autant plus qu'à l'époque MT4 et MT5 étaient sensiblement différents en termes d'implémentation de MQL). Cela m'a conduit à comprendre son erreur. Ce n'est pas une "sagesse", mais une limitation raisonnable, une sorte de "foolproof". Si vous vous souvenez toujours de ce dont chacune des centaines de variables est responsable, vous n'avez pas besoin d'encapsulation. Je ne m'en souviens pas, et je préfère avoir le moins possible d'entités disponibles dans chaque bloc d'un programme.

Dès que MT4 est apparu OOP - j'ai immédiatement commencé à traduire tous mes développements en une forme unique, basée sur des interfaces.

 
George Merts:

1. Ma pratique montre qu'en effet, c'est nécessaire. Cela m'a amené à comprendre son caractère fallacieux.

2. Je ne m'en souviens pas, et je préfère avoir accès à aussi peu d'entités que possible dans chaque bloc de programmes.

1. Il n'est jamais expliqué à quoi cela sert et quel est le sophisme. Comme il s'agit d'un type de données particulier, vous pouvez y configurer l'accès comme vous le souhaitez. L'exemple est clairement un choix malheureux.

2. Il est évidemment malavisé de refuser au programmeur l'accès à ses données dans son programme sous prétexte qu'il y commettra une erreur, car il devra créer toutes sortes de solutions de contournement complexes pour permettre au programmeur d'y accéder et créer un code instable avec de nombreux bogues possibles. C'est comme si l'on interdisait au conducteur de toucher le volant, puis que l'on inventait des interfaces de contournement pour qu'il puisse diriger la voiture au lieu du volant.

 
Andrei:

2. Interdire à un programmeur l'accès à ses données dans son programme sous prétexte qu'il risque d'y faire des erreurs - c'est manifestement un raisonnement erroné, car il faut alors créer toutes sortes de solutions de contournement sophistiquées pour permettre au programmeur d'y accéder et, ce faisant, on crée un code instable avec un tas de bogues possibles. C'est comme si l'on interdisait au conducteur de toucher le volant, puis que l'on inventait des interfaces de contournement pour qu'il puisse diriger la voiture au lieu du volant.

Non. N'importe où dans le code - seul ce qui est nécessaire à cet endroit doit être disponible - tout le reste doit être coupé, si possible.

Dans votre situation avec le conducteur - cela signifie qu'il est raisonnable d'interdire au conducteur de toucher le volant lorsque la voiture est garée. Il n'essaie donc pas de tourner une roue lorsque la voiture est garée - en effet, à ce moment-là, des capteurs d'alignement des roues, par exemple, peuvent être connectés aux roues, et le fait que le conducteur saisisse la roue entraînera des erreurs dans le réglage de ces angles.

L'idée est qu'à tout moment, seule la fonctionnalité dont le programme a besoin à ce moment-là est disponible pour lui, et tout le reste serait fermé. Je suis convaincu depuis longtemps que c'est le moyen de faire le moins d'erreurs possible.

 
George Merts:

Non. N'importe où dans le code - seul ce qui est nécessaire à cet endroit doit être disponible - tout le reste doit être élagué, si possible.

L'idée est qu'à chaque instant, seules les fonctions dont le programme a besoin à ce moment-là sont disponibles et que toutes les autres doivent être verrouillées. J'ai appris il y a longtemps que c'est la façon de faire le moins d'erreurs possible.

Se préoccuper constamment de ce qu'il faut interdire et de ce qu'il faut autoriser est évidemment une exigence très illogique, à moins bien sûr que le programmeur soit ivre lorsqu'il écrit du code et qu'il ne se contrôle pas pour ne pas écrire un tas de code qu'il ne comprend pas. Je pense que cela n'aidera pas un programmeur alcoolique et ivre à éviter les erreurs dans le code, et les personnes sobres n'en ont pas besoin en premier lieu.

 
Andrei:

Se préoccuper constamment de ce qu'il faut interdire et de ce qu'il faut autoriser est évidemment une exigence très illogique, à moins, bien sûr, que le programmeur ne s'assoie pour écrire du code alors qu'il est ivre et qu'il n'a aucun contrôle sur lui-même pour écrire beaucoup de code qu'il ne comprend pas. Je pense que cela n'aidera pas un programmeur alcoolique et ivre à éviter les erreurs dans le code, et les personnes sobres n'en ont pas besoin en premier lieu.

Il s'agit d'une exigence très logique à laquelle de nombreuses personnes sont confrontées.

Vous n'en avez pas besoin - eh bien... n'utilisez pas la POO.