Gemeinkosten für die PLO - Seite 3

 
George Merts:

1. Sie benötigen zum Beispiel ein Array von Objekten.

Man kann es prozedural machen, oder man kann es auf der Basis von CArrayObj und CObjest machen. Die Probleme beginnen, wenn man das Verhalten von z.B. dem Hinzufügen oder Entfernen von Objekten oder deren Sortierung ändern muss. In der OOP ist die Unterstützung für ein Zeigerarray und die Arbeit mit ihm in den Basisobjekten enthalten. Die Änderung von Nachfolgeobjekten, die tatsächlich in dem Array enthalten sind, hat keine Auswirkungen. Im prozeduralen Stil - bei der Änderung von realen Objekten, die in einem Array enthalten sind - sind in der Regel viel mehr Stellen betroffen, zumindest weil wir Änderungen in der Größe der Objekte berücksichtigen müssen. Das führt viel leichter zu Fehlern.

2. Plattformübergreifend - auch viel bequemer zu organisieren im OOP-Stil. Bei der Anfrage, sagen wir, einer Handelsposition, erhalten wir eine Schnittstelle, und es spielt keine Rolle, auf welcher Plattform wir arbeiten - die Schnittstelle bietet virtuelle Funktionen, auf denen Sie alle Daten zu allen Aufträgen (für MT4) oder Positionen (MT5) abrufen können, und vom Standpunkt des Experten aus gibt es keinen Unterschied. Der Expert Advisor muss nicht wissen, auf welcher Plattform er/sie arbeitet.

3) Nun, das "Finishing in der prozeduralen Programmierung" ist das "Schreiben von Objekten-Prozeduren", d.h. die Schaffung einiger Verbindungen zwischen Daten und Prozeduren, die in der OOP Objekte darstellen.

4. und dann haben wir, sagen wir, eine Reihe von Arten von Aufträgen, die eine Menge gemeinsam haben. Es wäre sinnvoll, ein Objekt COrderInfo zu schaffen, das das Basisobjekt wäre und dessen Erben verschiedene Arten von Aufträgen darstellen würden. Dabei unterstützt der Trade Processor (ich habe die Klasse CTradeProcessor) automatisch genau den Auftrag, der ihm übergeben wurde, durch die Prozeduren, die für die Verarbeitung dieses Auftrags erforderlich sind.

5) Es ist einfacher, Fehler dort zu finden, wo es die wenigsten Querverbindungen gibt. Dies wird durch Kapselung und Polymorphismus gewährleistet. Wir fordern die Schnittstelle für die Handelsposition (CTradePositionI) an und alle Verbindungen mit realen Klassen, die diese Position repräsentieren (CMT4PositionInfo, CMT5PositionInfo), werden nur über diese Schnittstelle hergestellt, was zu einer einfacheren Fehlerkorrektur beiträgt, als wenn wir direkt mit realen Funktionen arbeiten, die Handelspositionsdaten zurückgeben.

1. Und wozu?

Warum kann die gleiche Funktion nicht auf verschiedenen Plattformen kompiliert werden?

Es sollte den Text von Funktionen nach dem Strukturtyp verpacken, um die Handhabung in Analogie zur Handhabung einer Funktion als Klassenmitglied zu erleichtern. Dazu muss im Prinzip kein Objekt erstellt werden.

4. Es wäre sinnvoller, eine einzige Funktion mit ihren Einstellungen zu erstellen, anstatt mehrere Objekte und unnötige Verbindungen durch Schnittstellen zu multiplizieren.

5. Außerdem sollten alle diese Verbindungen programmiert und dann über die Schnittstellen und dergleichen nachverfolgt werden, bei denen es schwierig sein kann, Fehler zu finden. Diese Besetzung ist von Anfang an unnötig und sinnlos.

 
Andrei:

1. Zum Beispiel: Wozu?

2) Warum kann dieselbe Funktion nicht auf verschiedenen Plattformen kompiliert werden, so dass man keine Schnittstellen für sie erstellen muss?

Ich meinte damit, den Text von Funktionen nach dem Typ der Struktur zu packen, um einen bequemeren Zugriff zu ermöglichen, ähnlich wie bei der Adressierung einer Funktion als Klassenmitglied. Grundsätzlich darf kein Objekt zu diesem Zweck geschaffen werden.

4. Es ist klüger, eine einzige Funktion mit Einstellungen zu erstellen, anstatt mehrere Objekte und unnötige Verbindungen durch Schnittstellen zu multiplizieren.

5. Außerdem sollten alle diese Verbindungen programmiert und dann über die Schnittstellen und dergleichen nachverfolgt werden, bei denen es schwierig sein kann, Fehler zu finden. Diese Besetzung ist von Anfang an unnötig und sinnlos.

1. Nun, die Klasse CTradePosition ist im Wesentlichen eine Liste der offenen Aufträge. Und für diese wäre es sehr nützlich, eine Schnittstelle, eine Basisklasse und eigentliche Klassen zu haben.

2. Es gibt nur eine Schnittstelle. Für alle Plattformen. Und im Falle von OOP denken wir nicht wirklich darüber nach, wo wir gerade arbeiten. Wir müssen keine plattformabhängigen und auftragsabhängigen Dinge berücksichtigen.

Und was ist der Unterschied zwischen Objekt und Funktion in dieser Verpackung? Das ist es, was ich meine - es ist im Wesentlichen dasselbe. Im Falle eines Objekts wird auch eine automatische Konstruktorfunktion hinzugefügt, die jedoch standardmäßig leer ist.

4. Genau diese "Einzelfunktion mit Einstellungen" ist die Quelle der Probleme. Denn in der Regel gibt es eine Vielzahl von Einstellungen. Und sie sind nicht auf verschiedenen Ebenen der Klassenhierarchie verstreut, sondern in genau dieser Funktion konzentriert. Aber die Schnittstelle ermöglicht es Ihnen, alle Einstellungen, die in einem bestimmten Kontext nicht verwendet werden, "außer Acht" zu lassen - was sich sehr positiv auf das Verständnis des Codes und die Möglichkeiten von Fehlern und deren Erkennung auswirkt. Genau das ist der Hauptvorteil von OOP - die gesamte Funktionalität ist in Objekten auf verschiedenen Hierarchieebenen "verstreut", und wenn man mit diesem oder jenem Teil davon arbeitet, stören andere nicht. Bei einer einzigen Funktion mit Einstellungen hingegen sind alle Funktionen immer verfügbar, auch wenn sie überflüssig sind. Dies ist in der Regel eine Quelle von Problemen, weil man die Variablen versehentlich verwechseln kann. Der größte Nachteil ist, dass es viel schwieriger ist, Fehler in einer solchen einzelnen Funktion zu erkennen.

5. In jedem Fall werden diese Verknüpfungen benötigt und müssen programmiert werden - es handelt sich um die gleichen Einstellungen in einer einzigen Funktion. In meinem Beispiel beispielsweise haben wir in einer einzigen Funktion Zugang zu unterschiedlichen Plattformen, verschiedenen Auftragsarten, unterschiedlichen Positionsdarstellungen - all das muss berücksichtigt werden. Und wenn es eine Schnittstelle gibt, ist alles "abgeschnitten" - nur was in der Schnittstelle definiert ist, kann berücksichtigt werden.

Das ist der Sinn der Kapselung, den Zugriff von einem Codeblock auf einen anderen zu beschränken. Im Gegenteil, Sie schlagen vor, "eine große universelle Funktion mit maximalen Einstellungen" zu haben, so dass jeder, der Zugang zu dieser Funktion hat, maximale Möglichkeiten hat. Dies ist, wie meine Erfahrung zeigt, der falsche Weg. Der richtige Weg ist im Gegenteil, den Benutzer so weit wie möglich einzuschränken, wenn ein Block des Programms die Funktionalität eines anderen Blocks benötigt - er sollte nur diese Funktionalität haben, und kein bisschen mehr. Dies ist der Schlüssel zu einem stabileren und fehlerfreien Code.

 
George Merts:

1. Nun, die Klasse CTradePosition ist im Wesentlichen eine Liste der offenen Aufträge. Aufträge können unterschiedlich sein, und für sie ist es sehr praktisch, eine Schnittstelle, eine Basisklasse und echte Klassen zu haben.

Und was ist falsch daran, die Aufträge in einem Array von Strukturen zu halten, oder in der Art, wie es in MT4 implementiert ist?

 
Andrei:

Was ist falsch daran, Aufträge in einer Reihe von Strukturen oder wie in MT4 implementiert zu halten?

Denn jeder Benutzer hat zu viele Rechte und zu viele unnötige Informationen beim Zugriff auf dieses Feld.

Meiner Meinung nach ist es richtig, dem Nutzer nur den Teil der Funktionalität zu geben, den er braucht - und zwar über eine vorher vereinbarte Schnittstelle für den Zugriff auf Aufträge.

 
George Merts:

Jeder Benutzer hat zu viele Rechte und zu viele unnötige Informationen beim Zugriff auf dieses Feld.

Meiner Meinung nach ist es richtig, dem Nutzer nur den Teil der Funktionalität zu geben, den er braucht - und zwar über eine vorher vereinbarte Schnittstelle für den Zugriff auf die Aufträge.

Sie können Ihren eigenen Datentyp für Aufträge erstellen, es besteht keine Notwendigkeit für Schnittstellen, Objekte und andere unnötige Erfindungen, die zu unnötigen Fehlern und Instabilitäten führen.

 
Andrei:

Sie können Ihren eigenen Datentyp für Aufträge erstellen, es besteht keine Notwendigkeit für Schnittstellen, Objekte und andere unnötige Erfindungen, die unnötige Fehler und Instabilitäten verursachen.

Meine Erfahrung zeigt, dass Sie das müssen.

Ich habe diesen Weg vor etwa fünf Jahren eingeschlagen, damals noch mit MT4. (Nicht, weil ich keine Ahnung von OOP hatte, sondern weil ich zu faul war, mich mit Schnittstellen und Vererbung zu beschäftigen, zumal sich MT4 und MT5 damals in Bezug auf die MQL-Implementierung deutlich unterschieden). Dies führte mich zu der Erkenntnis, dass dies ein Trugschluss ist. Dies ist keine "Weisheit", sondern eine ziemlich vernünftige Einschränkung, eine Art "narrensicher". Wenn Sie sich immer daran erinnern, wofür jede von Hunderten von Variablen verantwortlich ist, brauchen Sie keine Kapselung. Daran kann ich mich nicht erinnern, und ich ziehe es vor, in jedem Programmblock so wenige Einheiten wie möglich zur Verfügung zu haben.

Sobald MT4 OOP erschien, habe ich sofort begonnen, alle meine Entwicklungen in eine einzige Form zu übersetzen, die auf Schnittstellen basiert.

 
George Merts:

1. Meine Praxis zeigt, dass dies in der Tat notwendig ist. Dies hat mich dazu gebracht, den Irrtum zu verstehen.

2. Ich kann mich nicht daran erinnern, und ich ziehe es vor, in jedem Software-Block so wenige Entitäten wie möglich zugänglich zu haben.

1. Es wird nie erklärt, wozu das gut sein soll und worin der Irrtum besteht. Da es sich hierbei um eine besondere Art von Daten handelt, können Sie den Zugriff dort nach Belieben einrichten. Das Beispiel ist eindeutig eine unglückliche Wahl.

2. Es ist offensichtlich falsch, dem Programmierer den Zugriff auf seine Daten in seinem Programm unter dem Vorwand zu verweigern, dass er dort einen Fehler machen wird, da er später verschiedene komplizierte Wege finden muss, um diesen Zugriff zu ermöglichen, was zu instabilem Code mit vielen möglichen Fehlern führen wird. Das ist so, als würde man dem Fahrer verbieten, das Lenkrad zu berühren, und dann Umgehungslösungen erfinden - Schnittstellen, mit denen er das Auto statt des Lenkrads steuern kann.

 
Andrei:

2. Einem Programmierer den Zugriff auf seine Daten in seinem Programm unter dem Vorwand zu verwehren, dass er dort angeblich Mist bauen würde - das ist offensichtlich ein Denkfehler, denn dann muss man alle möglichen ausgeklügelten Workarounds entwickeln, um dem Programmierer den Zugriff zu ermöglichen, und auf diese Weise entsteht instabiler Code mit einer Reihe möglicher Fehler. Das ist so, als würde man dem Fahrer verbieten, das Lenkrad zu berühren, und dann Umgehungslösungen erfinden - Schnittstellen, mit denen er das Auto statt des Lenkrads steuern kann.

Nein. Nur das, was an dieser Stelle benötigt wird, sollte verfügbar sein - alles andere sollte nach Möglichkeit abgeschnitten werden.

In Ihrer Situation mit dem Fahrer bedeutet dies, dass es vernünftig ist, dem Fahrer zu verbieten, das Lenkrad zu berühren, während das Auto geparkt ist. Er versucht also nicht, ein Rad zu drehen, während das Auto geparkt ist - zu diesem Zeitpunkt können nämlich z. B. Achsvermessungssensoren mit den Rädern verbunden sein, und ein Griff des Fahrers an das Rad führt zu Fehlern bei der Einstellung dieser Winkel.

Die Idee ist, dass zu einem bestimmten Zeitpunkt nur die Funktionen zur Verfügung stehen, die das Programm in diesem Moment benötigt, und alles andere geschlossen ist. Ich bin seit langem davon überzeugt, dass man auf diese Weise die wenigsten Fehler machen kann.

 
George Merts:

Nein. Nur das, was an dieser Stelle benötigt wird, sollte verfügbar sein - alles andere sollte nach Möglichkeit gestrichen werden.

Die Idee ist, dass dem Programm zu jedem Zeitpunkt nur die Funktionen zur Verfügung stehen, die in diesem Moment benötigt werden, alle anderen müssen gesperrt werden. Ich habe schon vor langer Zeit gelernt, dass man auf diese Weise die wenigsten Fehler machen kann.

Sich ständig damit zu beschäftigen, was verboten und was erlaubt ist, ist offensichtlich eine sehr unlogische Anforderung, es sei denn, der Programmierer ist beim Schreiben von Code betrunken und hat keine Kontrolle darüber, dass er vielleicht einen Haufen Code schreibt, den er nicht versteht. Ich denke, dass es einem alkoholisierten Programmierer nicht helfen wird, Fehler im Code zu vermeiden, und nüchterne Menschen brauchen es von Anfang an nicht.

 
Andrei:

Sich ständig Gedanken darüber zu machen, was verboten und was erlaubt werden soll, ist offensichtlich eine sehr unlogische Anforderung, es sei denn, der Programmierer setzt sich betrunken hin, um Code zu schreiben, und hat keine Kontrolle über sich selbst, dass er eine Menge Code schreiben kann, den er nicht versteht. Ich denke, dass es einem alkoholisierten Programmierer nicht helfen wird, Fehler im Code zu vermeiden, und nüchterne Menschen brauchen es gar nicht erst.

Dies ist eine sehr logische Forderung, die von vielen Menschen gestellt wird.

Sie brauchen es nicht - na ja... verwenden Sie kein OOP.