Diskussion zum Artikel "Implementierung eines Tabellenmodells in MQL5: Anwendung des MVC-Konzepts"

 

Neuer Artikel Implementierung eines Tabellenmodells in MQL5: Anwendung des MVC-Konzepts :

In diesem Artikel betrachten wir den Prozess der Entwicklung eines Tabellenmodells in MQL5 unter Verwendung des MVC-Architekturmusters (Model-View-Controller) zur Trennung der Logik, Darstellung und Steuerung der Daten, was strukturierten, flexiblen und skalierbaren Code ermöglicht. Wir betrachten die Implementierung von Klassen zum Aufbau eines Tabellenmodells, einschließlich der Verwendung von verknüpften Listen zur Speicherung von Daten.

Bei der Programmierung spielt die Anwendungsarchitektur eine Schlüsselrolle bei der Gewährleistung von Zuverlässigkeit, Skalierbarkeit und einfacher Unterstützung. Einer der Ansätze, der hilft, solche Ziele zu erreichen, ist die Nutzung eines Architekturmusters namens MVC (Model-View-Controller).

Das MVC-Konzept ermöglicht es, eine Anwendung in drei miteinander verbundene Komponenten zu unterteilen: model (Daten- und Logikverwaltung), View (Datenanzeige) und controller (Verarbeitung von Nutzeraktionen). Diese Trennung vereinfacht die Entwicklung, das Testen und die Wartung des Codes und macht ihn strukturierter und flexibler.

In diesem Artikel betrachten wir, wie man MVC-Prinzipien anwendet, um ein Tabellenmodell in der Sprache MQL5 zu implementieren. Tabellen sind ein wichtiges Hilfsmittel zum Speichern, Verarbeiten und Anzeigen von Daten, und ihre richtige Organisation kann die Arbeit mit Informationen erheblich erleichtern. Wir werden Klassen für die Arbeit mit Tabellen erstellen: Tabellenzellen, Zeilen und ein Tabellenmodell. Um Zellen innerhalb von Zeilen und Zeilen innerhalb des Tabellenmodells zu speichern, werden wir die Klassen der verknüpften Listen aus der MQL5-Standardbibliothek verwenden, die eine effiziente Speicherung und Verwendung von Daten ermöglichen.


Autor: Artyom Trishkin

 

Hallo, Artem.

Ich habe eine Frage:

Dein Code liest den Objekttyp.

      //--- Objekttyp lesen
      this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE);

Aber er wird nicht geprüft wie in SB

bool CList::Load(const int file_handle)
  {
   uint     i,num;
   CObject *node;
   bool     result=true;
//--- prüfen
   if(file_handle==INVALID_HANDLE)
      return(false);
//--- Lesen und Prüfen der Anfangsmarkierung - 0xFFFFFFFFFFFFFFFFFFFFF
   if(FileReadLong(file_handle)!=-1)
      return(false);
//--- Lesen und Prüfen des Typs
   if(FileReadInteger(file_handle,INT_VALUE)!=Type())
      return(false);
//--- Größe der Liste lesen
   num=FileReadInteger(file_handle,INT_VALUE);
//--- sequentielle Erstellung von Listenelementen durch den Aufruf der Methode Load()
   Clear();
   for(i=0;i<num;i++)
     {
      node=CreateElement();
      if(node==NULL)
         return(false);
      Add(node);
      result&=node.Load(file_handle);
     }
//--- erfolgreich
   return(result);
  }

Wie wir sehen können, gibt die Methode Type() einfach einen Wert zurück.

   virtual int       Type(void) const { return(0x7779); }

Wozu ist eine solche Prüfung in SB notwendig? Reicht es wirklich aus, den Typ zu lesen und ein Element des entsprechenden Typs zu erzeugen?

 
Alexey Viktorov #:
this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE);

Nun, wenn der Typ nicht gelesen wird, was dann?

Hier ist der Code:

//--- Sequentielle Neuerstellung der Listenelemente durch Aufruf der Load()-Methode von Knotenobjekten
   this.Clear();
   for(uint i=0; i<num; i++)
     {
      //--- Lesen und Prüfen der Objektdaten-Startmarkierung - 0xFFFFFFFFFFFFFFFFFFFFFFF
      if(::FileReadLong(file_handle)!=MARKER_START_DATA)
         return false;
      //--- Objekttyp lesen
      this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE);
      node=this.CreateElement();
      if(node==NULL)
         return false;
      this.Add(node);
      //--- Jetzt wird der Dateizeiger relativ zum Beginn der Objektmarke um 12 Bytes versetzt (8 - Marke, 4 - Typ).
      //--- Legen wir einen Zeiger auf den Anfang der Objektdaten und laden die Objekteigenschaften aus der Datei mit der Load()-Methode des Knotenelements.
      if(!::FileSeek(file_handle,-12,SEEK_CUR))
         return false;
      result &=node.Load(file_handle);
     }
//--- Ergebnis
   return result;
  }
//+------------------------------------------------------------------+
//| Methode zur Erstellung eines Listeneintrags|
//+------------------------------------------------------------------+
CObject *CListObj::CreateElement(void)
  {
//--- Abhängig vom Objekttyp in m_element_type, ein neues Objekt erstellen
   switch(this.m_element_type)
     {
      case OBJECT_TYPE_TABLE_CELL   :  return new CTableCell();
      case OBJECT_TYPE_TABLE_ROW    :  return new CTableRow();
      case OBJECT_TYPE_TABLE_MODEL  :  return new CTableModel();
      default                       :  return NULL;
     }
  }

Wir lesen den Typ des Objekts in eine Variable ein. Dann versuchen wir, dieses Objekt in CreateElement() zu erstellen, und es gibt Fälle. Was wird diese Methode zurückgeben, wenn der Typ des zu erstellenden Objekts nicht aus der Datei gelesen wird?

 
Artyom Trishkin #:

Nun, wenn die Schrift nicht gelesen wird, was dann?

Hier ist der Code:

Wir lesen den Typ des Objekts in eine Variable ein. Dann versuchen wir, dieses Objekt in CreateElement() zu erstellen, und es gibt Fälle. Was wird diese Methode zurückgeben, wenn der Typ des zu erstellenden Objekts nicht aus der Datei gelesen wird?

Artem, das ist nicht das, wovon ich spreche. Ich spreche von der Tatsache, dass es in SB eine Typüberprüfung gibt. Genau die Prüfung.

//--- Lesen und Prüfen des Typs
   if(FileReadInteger(file_handle,INT_VALUE)!= Type())
      return(false);

Stimmt der aus der Datei gelesene Typ mit dem Typ aus der Methode Type()Read and typecheck überein. Wird das so übersetzt?
Und Sie lesen einfach den Typ, ohne ihn zu prüfen.

Die Frage ist also: Was ist die tiefere Bedeutung dieser Prüfung?

 
Alexey Viktorov #:
Hier ist die Frage: Was ist die tiefere Bedeutung dieser Prüfung?

Wenn eine Klasse von SomeObject aus einer Datei geladen wird, indem die Load()-Methode eben dieses SomeObjects aufgerufen wird, wird geprüft, ob ich mich wirklich aus der Datei gelesen habe (das ist die Frage, die Sie stellen). Wenn nicht, bedeutet das, dass etwas schief gelaufen ist, und es hat keinen Sinn, weiter zu laden.

Was ich hier habe, ist eine LISTE (CListObj), die einen Objekttyp aus einer Datei liest. Die Liste weiß nicht, was sich in der Datei befindet (welches Objekt). Aber sie muss diesen Objekttyp kennen, um ihn in ihrer CreateElement()-Methode zu erzeugen. Deshalb prüft sie nicht den Typ des geladenen Objekts aus der Datei. Schließlich wird es einen Vergleich mit Type() geben, der in dieser Methode den Typ einer Liste und nicht eines Objekts zurückgibt.

 
Artyom Trishkin #:

Wenn eine Klasse von SomeObject aus einer Datei geladen wird, indem man die Load()-Methode von eben diesem SomeObject aufruft, wird geprüft, ob ich mich wirklich aus der Datei eingelesen habe (das ist die Frage, die Sie stellen). Wenn nicht, bedeutet das, dass etwas schief gelaufen ist und es keinen Sinn hat, weiter zu laden.

Was ich hier habe, ist eine LISTE (CListObj), die einen Objekttyp aus einer Datei liest. Die Liste weiß nicht, was sich in der Datei befindet (welches Objekt). Aber sie muss diesen Objekttyp kennen, um ihn in ihrer CreateElement()-Methode zu erzeugen. Deshalb prüft sie nicht den Typ des geladenen Objekts aus der Datei. Schließlich wird es einen Vergleich mit Type() geben, der in dieser Methode den Typ einer Liste und nicht eines Objekts zurückgibt.

Danke, ich habe es herausgefunden, ich verstehe.

 

Ich habe es gelesen, und dann habe ich es noch einmal gelesen.

ist etwas anderes als ein "Modell" in MVC. Einige ListStorage zum Beispiel

 
Lassen Sie uns zur Sache kommen. Behalten Sie Ihre Meinung für sich.
 
Ich frage mich. Ist es möglich, einige Analogon von Python und R dataframes auf diese Weise zu erhalten? Dies sind Tabellen, wo verschiedene Spalten Daten verschiedener Typen enthalten können (aus einer begrenzten Menge von Typen, aber einschließlich String).
 
Aleksey Nikolayev #:
Ich frage mich. Ist es möglich, einige Analogon von Python und R dataframes auf diese Weise zu erhalten? Dies sind solche Tabellen, in denen verschiedene Spalten Daten verschiedener Typen enthalten können (aus einer begrenzten Anzahl von Typen, aber einschließlich String).

Sie können. Wenn wir über verschiedene Spalten einer Tabelle sprechen, dann kann in der beschriebenen Implementierung jede Zelle der Tabelle einen anderen Datentyp haben.