"MQL5'te bir tablo modelinin uygulanması: MVC konseptini uygulama" makalesi için tartışma

 

Yeni makaleye göz atın: MQL5'te bir tablo modelinin uygulanması: MVC konseptini uygulama.

Bu makalede, veri mantığını, sunumu ve kontrolü ayırarak yapılandırılmış, esnek ve ölçeklenebilir kod sağlayan MVC (Model-View-Controller) mimari modelini kullanarak MQL5'te bir tablo modeli geliştirme sürecini ele alacağız. Verileri depolamak için bağlantılı listelerin kullanımı da dahil olmak üzere bir tablo modeli oluşturmak için sınıfların uygulanmasını inceleyeceğiz.

Programlamada, uygulama mimarisi güvenilirlik, ölçeklenebilirlik ve destek kolaylığı sağlamada önemli bir rol oynar. Bu tür hedeflere ulaşmaya yardımcı olan yaklaşımlardan biri, MVC (Model-View-Controller) mimari modelden yararlanmaktır.

MVC konsepti, bir uygulamayı birbiriyle ilişkili üç bileşene ayırmanıza olanak tanır: model (veri ve mantık yönetimi), görünüm (veri görüntüleme) ve kontrolcü (kullanıcı eylemlerini işleme). Bu ayrım, kod geliştirme, test ve bakımı basitleştirerek daha yapılandırılmış ve esnek hale getirir.

Bu makalede, MQL5 dilinde bir tablo modeli uygulamak için MVC ilkelerinin nasıl uygulanacağını ele alacağız. Tablolar verilerin depolanması, işlenmesi ve görüntülenmesi için önemli bir araçtır ve uygun şekilde düzenlenmeleri bilgilerle çalışmayı çok daha kolay hale getirebilir. Tablolarla çalışmak için sınıflar oluşturacağız: tablo hücresi, tablo satırı ve tablo modeli. Hücreleri satırlar içinde ve satırları tablo modeli içinde depolamak için, verilerin verimli bir şekilde depolanmasına ve kullanılmasına olanak tanıyan MQL5 Standart Kütüphanesindeki bağlantılı liste sınıflarını kullanacağız.


Yazar: Artyom Trishkin

 

Merhaba, Artem.

İşte bir soru:

Kodunuz nesne türünü okuyor.

      //--- Nesne türünü oku
      this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE);

Ancak SB'de olduğu gibi kontrol edilmez

bool CList::Load(const int file_handle)
  {
   uint     i,num;
   CObject *node;
   bool     result=true;
//--- kontrol et
   if(file_handle==INVALID_HANDLE)
      return(false);
//--- başlangıç işaretleyicisini okuma ve kontrol etme - 0xFFFFFFFFFFFFFFFFF
   if(FileReadLong(file_handle)!=-1)
      return(false);
//--- okuma ve tip kontrolü
   if(FileReadInteger(file_handle,INT_VALUE)!=Type())
      return(false);
//--- liste boyutunu oku
   num=FileReadInteger(file_handle,INT_VALUE);
//--- Load() yöntemi çağrısı kullanılarak liste öğelerinin sıralı olarak oluşturulması
   Clear();
   for(i=0;i<num;i++)
     {
      node=CreateElement();
      if(node==NULL)
         return(false);
      Add(node);
      result&=node.Load(file_handle);
     }
//--- başarılı
   return(result);
  }

Gördüğümüz gibi, Type() yöntemi basitçe bir değer döndürür

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

SB'de böyle bir kontrolün gerekliliği nedir? Türü okumak ve ilgili türde bir eleman oluşturmak gerçekten yeterli mi?

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

Peki, tür okunmazsa, sonra ne olacak?

İşte kod:

//--- Düğüm nesnelerinin Load() yöntemini çağırarak liste öğelerini sırayla yeniden oluşturun
   this.Clear();
   for(uint i=0; i<num; i++)
     {
      //--- Nesne verisi başlangıç işaretleyicisini okuyun ve kontrol edin - 0xFFFFFFFFFFFFFFFFFFF
      if(::FileReadLong(file_handle)!=MARKER_START_DATA)
         return false;
      //--- Nesne türünü oku
      this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE);
      node=this.CreateElement();
      if(node==NULL)
         return false;
      this.Add(node);
      //--- Şimdi dosya işaretçisi, nesne işaretçisinin başlangıcına göre 12 bayt (8 - işaretçi, 4 - tür) kaydırılır.
      //--- Nesne verilerinin başına bir işaretçi koyalım ve düğüm öğesinin Load() yöntemini kullanarak nesne özelliklerini dosyadan yükleyelim.
      if(!::FileSeek(file_handle,-12,SEEK_CUR))
         return false;
      result &=node.Load(file_handle);
     }
//--- Sonuç
   return result;
  }
//+------------------------------------------------------------------+
//| Liste öğesi oluşturma yöntemi|
//+------------------------------------------------------------------+
CObject *CListObj::CreateElement(void)
  {
//--- m_element_type içindeki nesne türüne bağlı olarak, yeni bir nesne oluşturun
   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;
     }
  }

Nesnenin türünü bir değişkene okuyun. Sonra bu nesneyi CreateElement() içinde oluşturmaya çalışıyoruz ve durumlar var. Oluşturulan nesnenin türü dosyadan okunmazsa bu metot ne döndürecek?

 
Artyom Trishkin #:

Peki, yazı okunmazsa, sonra ne olacak?

Kod burada:

Nesnenin türünü bir değişkene okuyoruz. Sonra CreateElement() içinde bu nesneyi oluşturmaya çalışıyoruz ve durumlar var. Oluşturulmakta olan nesnenin türü dosyadan okunmazsa bu yöntem ne döndürür?

Artem, bahsettiğim şey bu değil. SB'de bir tür kontrolü olduğu gerçeğinden bahsediyorum. Tam olarak kontrol.

//--- okuma ve tip kontrolü
   if(FileReadInteger(file_handle,INT_VALUE)!= Type())
      return(false);

Dosyadan okunan tip, Type()Read ve tipkontrol metodundaki tiple eşleşiyor mu? Bu şekilde mi çevriliyor?
Ve siz sadece türü kontrol etmeden okuyorsunuz.

Yani soru şu: Bu kontrolün derin anlamı nedir?

 
Alexey Viktorov #:
İşte soru: Bu kontrolün derin anlamı nedir?

SomeObject'in bir sınıfı, bu SomeObject'in Load() yöntemi çağrılarak bir dosyadan yüklendiğinde, "kendimi gerçekten dosyadan okudum mu?" diye kontrol eder (sorduğunuz şey budur). Eğer değilse, bir şeyler yanlış gitmiş demektir, bu yüzden daha fazla yükleme yapmanın bir anlamı yoktur.

Burada sahip olduğum şey, bir dosyadan bir nesne türünü okuyan bir LİSTE (CListObj). Liste dosyada ne olduğunu (hangi nesne) bilmiyor. Ancak CreateElement() metodunda oluşturmak için bu nesne tipini bilmesi gerekir. Bu yüzden dosyadan yüklenen nesnenin türünü kontrol etmez. Sonuçta, bu yöntemde bir nesnenin değil, bir listenin türünü döndüren Type() ile bir karşılaştırma yapılacaktır.

 
Artyom Trishkin #:

SomeObject'in bir sınıfı, bu SomeObject'in Load() yöntemi çağrılarak bir dosyadan yüklendiğinde, "kendimi gerçekten dosyadan okudum mu?" diye kontrol eder (sorduğunuz şey budur). Aksi takdirde, bir şeylerin yanlış gittiği anlamına gelir, bu nedenle daha fazla yüklemenin bir anlamı yoktur.

Burada sahip olduğum şey, bir dosyadan bir nesne türünü okuyan bir LİSTE (CListObj). Liste dosyada ne olduğunu (hangi nesne) bilmiyor. Ancak CreateElement() metodunda oluşturmak için bu nesne türünü bilmesi gerekir. Bu yüzden dosyadan yüklenen nesnenin türünü kontrol etmez. Sonuçta, bu yöntemde bir nesnenin değil, bir listenin türünü döndüren Type() ile bir karşılaştırma yapılacaktır.

Teşekkürler, anladım, anladım.

 

Okudum ve sonra tekrar okudum.

MVC'de bir "model "den başka bir şey değildir. Örneğin bazı ListStorage

 
İşimize bakalım. Fikirlerinizi kendinize saklayın.
 
Merak ediyorum. Bu şekilde python ve R veri çerçevelerinin bir benzerini elde etmek mümkün mü? Bunlar, farklı sütunların farklı türlerde veriler içerebildiği tablolardır (sınırlı bir tür kümesinden, ancak dize dahil).
 
Aleksey Nikolayev #:
Merak ediyorum. Bu şekilde python ve R veri çerçevelerinin bir benzerini elde etmek mümkün mü? Bunlar, farklı sütunların farklı türlerde (sınırlı bir tür kümesinden, ancak dize dahil) veri içerebileceği tablolardır.

Yapabilirsiniz. Bir tablonun farklı sütunlarından bahsediyorsak, açıklanan uygulamada tablonun her hücresi farklı bir veri türüne sahip olabilir.