こんにちは、アルテム。
質問があります:
あなたのコードはオブジェクトタイプを読み取ります。
//--- オブジェクト・タイプの読み取り this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE);
しかし、SBのようにチェックされていません。
bool CList::Load(const int file_handle) { uint i,num; CObject *node; bool result=true; //--- チェック if(file_handle==INVALID_HANDLE) return(false); //--- 開始マーカーの読み取りとチェック - 0xFFFFFFFFFFFFFFFFF if(FileReadLong(file_handle)!=-1) return(false); //---タイプの読み取りとチェック if(FileReadInteger(file_handle,INT_VALUE)!=Type()) return(false); //--- リストのサイズを読み込む num=FileReadInteger(file_handle,INT_VALUE); //--- メソッドLoad()の呼び出しを使って、リスト項目を順次作成する。 Clear(); for(i=0;i<num;i++) { node=CreateElement(); if(node==NULL) return(false); Add(node); result&=node.Load(file_handle); } //--- 成功 return(result); }
見てわかるように、Type()メソッドは単に値を返します。
virtual int Type(void) const { return(0x7779); }
SBではこのようなチェックは必要なのでしょうか?型を読み取り、対応する型の要素を作成するだけで本当に十分なのでしょうか?
さて、型が読み込まれなかったら、次はどうする?
これがそのコードだ:
//--- ノード・オブジェクトの Load() メソッドを呼び出して、リスト項目を逐次再作成する。 this.Clear(); for(uint i=0; i<num; i++) { //--- オブジェクト・データのスタート・マーカーを読み取り、チェックする - 0xFFFFFFFFFFFFFFFFFFF if(::FileReadLong(file_handle)!=MARKER_START_DATA) return false; //--- オブジェクト・タイプの読み取り this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE); node=this.CreateElement(); if(node==NULL) return false; this.Add(node); //--- これで、ファイル・ポインターはオブジェクト・マーカーの先頭から12バイト(8-マーカー、4-タイプ)だけ相対的にオフセットされる。 //--- オブジェクト・データの先頭にポインタを置き、ノード要素のLoad()メソッドを使ってファイルからオブジェクト・プロパティをロードしてみましょう。 if(!::FileSeek(file_handle,-12,SEEK_CUR)) return false; result &=node.Load(file_handle); } //--- 結果 return result; } //+------------------------------------------------------------------+ //| リスト項目の作成方法| //+------------------------------------------------------------------+ CObject *CListObj::CreateElement(void) { //--- m_element_typeのオブジェクト・タイプに応じて、新しいオブジェクトを作成する。 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; } }
オブジェクトの型を変数に読み込む。次に、CreateElement()でこのオブジェクトを作成しようとする。作成されるオブジェクトの型がファイルから読み取られなかった場合、このメソッドは何を返すでしょうか?
さて、タイプが読まれなかったら、次はどうする?
これがそのコードだ:
オブジェクトの型を変数に読み込みます。次に、CreateElement()でこのオブジェクトを作成しようとする。作成されるオブジェクトの型がファイルから読み取られなかった場合、このメソッドは何を返すでしょうか?
アーテム、私が話しているのはそういうことではない。SBには型チェックがあるという事実を話しているんだ。まさにそのチェックだ。
//---タイプの読み取りとチェック if(FileReadInteger(file_handle,INT_VALUE)!= Type()) return(false);
ファイルから読み込まれた型が、Type()Readと 型チェック メソッドから読み込まれた型と一致するかどうか。そう変換されるのか?
そして、それをチェックせずにただ型を読み取る。
そこで疑問なのは、このチェックの深い意味は何なのかということだ。
このチェックの深い意味は何だろう?
SomeObjectのクラスがファイルからロードされるとき、まさにこのSomeObjectのLoad()メソッドを呼び出すと、"本当にファイルから自分自身を読み込んだのか?"をチェックする(それがあなたが尋ねていることだ)。もしそうでなければ、何かが間違っていることを意味するので、それ以上ロードする意味はない。
ここにあるのは、ファイルからオブジェクト・タイプを読み込んでいるリスト(CListObj)だ。リストは、ファイルに何があるか(どんなオブジェクトか)を知らない。しかし、CreateElement()メソッドでオブジェクトを作成するには、このオブジェクト・タイプを知っていなければなりません。だから、ファイルから読み込まれたオブジェクトの型をチェックしないのです。結局のところ、このメソッドではオブジェクトではなくリストの型を返すType()と比較することになる。
このSomeObjectのLoad()メソッドを呼び出すことで、SomeObjectのクラスがファイルからロードされると、「本当にファイルから読み込んだのか?もしそうでなければ、何かが間違っていたことを意味するので、それ以上ロードする意味はない。
ここにあるのは、ファイルからオブジェクト・タイプを読み込むリスト(CListObj)だ。リストは、ファイルに何があるか(どんなオブジェクトか)を知らない。しかし、CreateElement()メソッドでオブジェクトを生成するためには、このオブジェクト・タイプを知っていなければなりません。だから、ファイルから読み込まれたオブジェクトの型をチェックしないのです。結局のところ、このメソッドではオブジェクトではなくリストの型を返すType()と比較することになる。
ありがとう、わかりました。
私はそれを読み、そしてまた読み直した。
MVCにおける "モデル "以外の何物でもない。例えば
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
新しい記事「MQL5でのテーブルモデルの実装:MVC概念の適用」はパブリッシュされました:
プログラミングにおいて、アプリケーションのアーキテクチャは、信頼性、拡張性、保守性を確保する上で非常に重要です。これらの目的を達成する手法のひとつが、MVC (Model-View-Controller)と呼ばれるアーキテクチャパターンの活用です。
MVCの概念は、アプリケーションを3つの相互関連するコンポーネントに分割します。モデル(データとロジックの管理)、ビュー(データの表示)、コントローラー(ユーザー操作の処理)です。この分離により、コードの開発、テスト、保守が容易になり、より構造化され柔軟な設計が可能になります。
本記事では、MQL5言語にMVCの原則を適用してテーブルモデルを実装する方法を考えます。テーブルはデータの格納、処理、表示において重要なツールであり、適切に組織化することで情報の扱いやすさが大きく向上します。テーブルを扱うためのクラスとして、テーブルセル、行、テーブルモデルを作成します。また、行内のセルやテーブルモデル内の行の格納には、MQL5標準ライブラリのリンクリストクラスを使用し、効率的なデータ格納と操作を可能にします。
作者: Artyom Trishkin