Fragen zu OOP (Objektorientierte Programmierung) - Seite 2

 
VOLDEMAR:

Wie immer wollte ich etwas lernen, aber es gibt sicher einige, die nichts mehr zu sagen haben, außer dass sie schlau sind...

Ich habe ein einfaches Beispiel geschrieben, um es zu zerlegen, ich weiß nicht, wie man kompetenter mit OOP schreiben kann ... Es ist nur ein Beispiel, wenn Sie wissen, wie man einen ähnlichen Code korrekt und OOP schreiben, dann schreiben Sie bitte, so dass ich und andere lernen könnten ...

OOP beginnt mit der Suche nach einem Objekt. Wenn es kein Objekt gibt, gibt es auch keine OOP.

In der Regel handelt es sich bei einem Objekt um einige Ressourcen, Daten.

Man muss nur schreiben und beobachten, wie andere schreiben. Dann werden Sie es selbst herausfinden. Sie können auch Lehrbücher lesen. Davon gibt es viele im Internet.

 
Zhunko:

OOP beginnt mit der Suche nach einem Objekt. Wenn es kein Objekt gibt, gibt es auch keine OOP.

In der Regel handelt es sich bei einem Objekt um einige Ressourcen, Daten.

Man muss nur schreiben und beobachten, wie andere schreiben. Dann werden Sie es selbst herausfinden. Sie können auch Lehrbücher lesen. Davon gibt es viele im Internet.


Empfehlen Sie bitte ein paar Lehrbücher ... Am einfachsten und nützlichsten ist Ihrer Meinung nach ...
 
VOLDEMAR:

Empfehlen Sie bitte ein paar Tutorials ... Am einfachsten und nützlichsten ist Ihrer Meinung nach ...

Grady Buch. "Objektorientierte Analyse und Entwurf. Mit Beispielen von C++-Anwendungen".

Ire Paul (manchmal auch Ira Paul geschrieben) "Objektorientierte Programmierung in C++".

 

1) Es hat zwar nichts mit OOP zu tun, aber es sollten Fehlerbehandlungen für Handelsoperationen(OrderSend(), OrderDelete(), OrderModify() ) hinzugefügt werden...

Um sie für OOP relevant zu machen, sollten Sie sie als virtuelle Klassenmethode einrichten (um sie in nachgeordneten Klassen zu überschreiben und die Verarbeitung von anderen Codes hinzuzufügen).

2) Alle Klassenmethoden, die in den Nachfolgeklassen anders funktionieren können als jetzt - machen Sie sievirtuell.

Der erste Kandidat ist openorders().

Der Nachteil ist, dass Sie bei virtuellen Methoden die Anzahl und den Typ der Parameter nicht ändern können.

Positiv ist, dass die "alten" Buy, Sel, BuyStop usw. in der Lage sein werden, die "neuen" (in der Child-Klasse geänderten) openorders() aufzurufen

3) Wir wollen sofort schönere Namen haben. OpenOrders statt openorders, zum Beispiel.

4) Wenn die Terminologie dazu dient, etwas zu nennen, dann verwendet man eine ähnliche Terminologie.

Wenn Verkaufen = VERKAUFEN, dann nennen Sie es Verkaufen oder SELL (d.h. SellStop statt SelStop)

5) Sie müssen alle Konstanten (500, etc.) aus der Klasse entfernen.

Sie können aus Variablen entnommen oder als Parameter von Methoden gesetzt werden.

Jetzt erinnern Sie sich an etwa 500 in openorders() eingebettete Klassen, aber später werden Sie es vergessen oder viele Eulen schreiben, die diese Klassen verwenden, und es wird schwierig sein, etwas zu ändern.

Am schwierigsten zu beheben sind architektonische Fehler.

Und das ist das Gerüst, das Sie jetzt erstellen (wenn es nicht nur eine Übung ist).

6) Packen Sie nicht alles in eine Klasse.

Erstellen Sie eine clOrder-Klasse und fügen Sie SetSL, CloseOrder, GetSL, GetProfit, SetTP, GetTP , etc. hinzu.

Fügen Sie in der Klasse clTrade ein Array/eine Liste von Aufträgen, ein Symbol und Symboleigenschaften(TICKETSIZE, POINT, TICKETVALUE, MINLOT, MAXLOT, STOPSTEP, LOTSTEP, LOTSIZE usw.) hinzu.

Wenn Sie Ask und Bid (als Eigenschaften eines Symbols) anhängen, vergessen Sie nicht, sie in OnTick() zu aktualisieren.

Zu RefreshRates(), machen Sie eine Bindung, so dass nach der Aktualisierung der МТ Variablen Ask und Bid Eigenschaften aufgerufen werden (Ich habe auch den Status der Aufträge, die geöffnet und die geschlossen überprüft. Die abgeschlossenen Aufträge werden aus der Liste der Aufträge entfernt).

Sie können einen Zeitplan (machen Sie zunächst eine Klasse) und einen Nachlaufstopp (machen Sie ebenfalls eine separate Klasse) hinzufügen.

PS: Ich habe alles am Wochenende gemacht (ich habe die Bibliothek für den Handel gemacht), aber dieses Mal habe ich ohne Klassen entschieden (nur Strukturen, Arrays von Strukturen und Funktionen, die mit all dem arbeiten).

Es gibt auch einen Zeitplan für jeden Tag (da Alps on gold jeden Tag von 0:00 bis 1:00 Uhr eine Pause hat). In den letzten 2 Minuten des Handels schließt der Schedule Checker alle Geschäfte und storniert alle Aufträge.

Und in der letzten Handelsstunde schließt er die Verlustgeschäfte, storniert die Aufträge und löst die Gewinngeschäfte aus. Ich habe auch einen Trailing-Stop gesetzt. Ein Typ, der jedoch aufgrund unterschiedlicher Parameter zu verschiedenen Symbolen passt.

Das Schema sieht folgendermaßen aus: Symbole (mit eigenen Feldern), Aufträge (mit eigenen Feldern), Zeitpläne (mit eigenen Feldern) und ein Expert Advisor mit eigenen Feldern (Magie usw.), der sich auf ein Symbol bezieht und eine Liste von Aufträgen und eine Liste von Zeitplänen hat.

An der Spitze der Hierarchie steht die Liste der Berater (die Kombination Symbol+Magie muss eindeutig sein).

 
VOLDEMAR:

Empfehlen Sie bitte einige Tutorials ... Die Ihrer Meinung nach einfachste und nützlichste ...

Beispiele, die mit OOP geschrieben wurden, sind jetzt in CodeBase zu finden. Von VOLDEMAR, zum Beispiel ))))

Eigentlich war es Ihre https://www.mql5.com/ru/code/11159, die mich dazu inspiriert hat, meine Handelsbibliothek für Strukturen neu zu schreiben.

Ich habe beschlossen, mit Klassen zu warten - ich sehe nicht den Sinn, sie in MQL zu verwenden .

 
Ich verstehe nicht ganz, ist es jetzt möglich, die Standardhandelsklasse zu verwenden?
Oder ist das nur in MQL5 Standard und wurde erst von dort in den neuen MetaEditor übernommen?
 
EverAlex:

Beispiele, die mit OOP geschrieben wurden, erscheinen jetzt in CodeBase. Von VOLDEMAR, zum Beispiel ))))

Eigentlich war es Ihre https://www.mql5.com/ru/code/11159, die mich dazu inspiriert hat, meine Handelsbibliothek für Strukturen neu zu schreiben.

Ich habe beschlossen, mit Klassen zu warten - ich sehe nicht den Sinn der Verwendung von ihnen in MQL so weit.


Ja, ich habe das geschrieben, aber abgesehen von der Übertragung von Funktionen in eine Klasse habe ich noch nichts anderes verstanden,
 
VOLDEMAR:

Ja, das habe ich geschrieben, aber abgesehen von der Übertragung von Funktionen in eine Klasse habe ich noch nichts anderes verstanden,

3(+1) OOP-Grundsätze:

1) Verkapselung. D.h. das Speichern von Variablen, Pseudovariablen (genannt "Objekteigenschaften" oder einfach "Eigenschaften") im Objekt selbst. D.h. wenn eine Klasse korrekt deklariert ist, können ihre Daten nicht von außen verändert werden.

Nur durch die Verwendung von Funktionen der Klasse selbst (die als "Klassenmethoden" oder einfach "Methoden" bezeichnet werden). Erforderlich, um einer Variablen nicht nur einen Wert zuzuweisen, sondern um eine Aktion im Zusammenhang mit der Änderung dieser Felder durchzuführen.

Und dies ist (meiner Meinung nach) der Hauptnutzen der Einführung von OOP in MQL, anstatt Funktionen zu portieren (die Funktionen meiner Handelsbibliothek erhalten den Index des EA als einen der Parameter und arbeiten mit dem ausgewählten EA, einschließlich seines Arrays von Aufträgen).

Niemand kann in die Daten einer von Ihnen erstellten Klasse eindringen (wenn es keinen Quellcode gibt) und sich dann beschweren, dass Ihr Code Fehler enthält.

2) Vererbung. Wenn eine Vorgängerklasse erstellt wird, erbt sie alle Felder und Methoden der Vorgängerklasse (es gibt einen privaten Typ für die Felder und Methoden, der in den Vorgängerklassen nicht sichtbar ist, aber das lassen wir jetzt mal weg).

Und hier, in der Entwurfsphase des Objekts, müssen Sie die Architektur klar durchdenken - wie die Klasse verwendet werden soll, welche Felder sie enthalten soll, wie sie in den Nachfolgeklassen sichtbar sein sollen, usw.

Sie wird in leistungsfähigen Systemen und Klassenbibliotheken für Aufgaben verwendet, die ich persönlich nicht in Handelsaufgaben sehe. Aber vielleicht braucht sie ja jemand. Sie können z.B. absteigende Klassen mit unterschiedlichen Endanschlägen bilden.

Deshalb - keine Konstanten innerhalb von Methoden, alles muss extern über entsprechende Methoden (beginnen meist mit .Set) oder direkt als Parameter von Methoden gesetzt werden. Das ist es, was ich mit Ihren 500 meine.

3) Polymorphismus. Die Sache, die ich schrieb ein paar Beiträge oben - wenn ein umgestaltet in einem abhängigen Klasse Funktion openorders() wird frei rufen Sie die alten Buy() Funktionen.

Ein Beispiel für Polymorphismus ist die Berechnung der Fläche einer geometrischen Figur für verschiedene Formen.

Für einen Kreis wird sie auf eine Weise berechnet, für ein Quadrat auf eine andere. Aber in jedem Fall - durch den Aufruf von Figura.GetSquare() erhalten wir die Fläche einer bestimmten Form, die von einer Basisklasse geerbt wurde (wenn wir nicht vergessen haben, Square() zu deklarieren).

Auch hier ist eine gewisse Qualifikation erforderlich, um die Architektur der Basisklasse zu erstellen. Wenn Sie beispielsweise vergessen, Square() als virtuell zu deklarieren, ist es unmöglich, Square auf generische Weise aufzurufen (Sie müssen vor jedem Aufruf den Klassentyp überprüfen und dessen Implementierung von Square aufrufen).

Einige Leute empfehlen, alle Methoden außer den Konstruktoren virtuell zu machen (ich vertrete die gleiche Ansicht, wenn man nicht den Horizont dessen sieht, was aus dieser Klasse werden kann, wenn man sie erstellt). Das Wichtigste ist, dass auch die Destruktoren virtuell sein müssen.


Aktualisierung:

================

4) Abstraktion (wie von den Genossen gefordert, obwohl, wenn ich studierte OOP (in den 1990er Jahren) war es nicht als ein Prinzip (denn in der Tat - nur von den ersten drei abgeleitet), und in dem Artikel (siehe Link unten) ist es darüber geschrieben, aber es ist nicht in den Titel des Artikels, gibt es nur 3).

In der praktischen Anwendung bedeutet dies, dass eine "leere" Basisklasse erstellt wird (in der Methoden deklariert sind, aber nichts tun). In einigen Sprachen kann eine Methode als abstrakt gekennzeichnet werden, was bedeutet, dass sie in einer Nachfolgeklasse zwangsläufig überlagert werden muss (d.h. eine Methode, die etwas tut, wird hinzugefügt).

===================

PS: Sie können kurz, ohne ins Detail zu gehen, hier lesen


PPS: Ich möchte niemanden beleidigen, aber als ich in Work fragte, ob ich eine Handelsbibliothek schreiben soll, antwortete nur 1 Person, dass er sie hat und benutzt.

5 MQL-Programmierer (über Skype) sagten, sie hätten keine Ahnung, was drin sein sollte, und sie fügten die erforderlichen Funktionen von einer ihrer Eulen in eine andere ein. Sie schieben RefreshRates() sogar zwischen Codefragmente, die nichts ändern und nicht länger als ein paar Millisekunden ausgeführt werden können. Und der nachfolgende Code hängt nicht von geänderten Ask und Bid und (vielleicht) Ordertypen ab.

Für MQL-Programmierer, die noch nie mit OOP in anderen Programmiersprachen gearbeitet haben, wird die OOP in MQL daher nicht nützlich sein. Bestenfalls werden Daten vor externen Änderungen verborgen (was auch nicht schlecht ist).

 
EverAlex:

3) Die 3 Prinzipien der OOP:

1) Verkapselung. D.h. Speicherung von Variablen, Pseudovariablen (bezeichnet als "Objekteigenschaften" oder einfach "Eigenschaften") im Objekt selbst. D.h. wenn eine Klasse korrekt deklariert ist, können ihre Daten nicht

2) Vererbung. Wenn eine Vorgängerklasse erstellt wird, erbt sie alle Felder und Methoden der Vorgängerklasse (es gibt einen privaten Typ für Felder und Methoden, der in den Vorgängerklassen nicht sichtbar ist, aber wir lassen ihn hier erst einmal weg).

3) Polymorphismus. Was ich ein paar Beiträge weiter oben geschrieben habe - wenn die Funktion openorders() in einer Nachfolgeklasse umgestaltet wird, werden die alten Funktionen Buy() usw. sicher aufgerufen.

Ein Beispiel für Polymorphismus ist die Berechnung der Fläche einer geometrischen Figur für verschiedene Formen.

Sie wird für einen Kreis auf die eine und für ein Quadrat auf die andere Weise berechnet. Aber in jedem Fall erhalten wir durch den Aufruf von Figura.GetSquare() die Fläche einer bestimmten, von der Basisklasse geerbten Form (es sei denn, wir haben vergessen, Square() zu deklarieren).

Wo ist der vierte?! Wo ist die Zusammenfassung? Unverdientermaßen vergessen :-(
 
Zhunko:
Wo ist der vierte?! Wo ist die Zusammenfassung? Unverdienterweise vergessen :-(


Hinzufügen.