OOP(オブジェクト指向プログラミング)に関する質問 - ページ 2

 
VOLDEMAR:

いつもながら、勉強になるなあと思いつつも、もう利口としか言いようがない人もいるはず...。

私はそれを分解するために簡単な例を書きました、私はOOPでより有能な書き方を知りません......これは単なる例であり、あなたが正しく、OOPで同様のコードを記述する方法を知っている場合は、私や他の人が学ぶことができるように、書いてください...

OOPはオブジェクトを見つけるところから始まります。オブジェクトがなければ、OOPは存在しない。

通常、オブジェクトは何らかのリソース、データである。

書いて、他の人がどう書くかを見るだけでいいんです。そうすれば、自分自身で解決することができます。教科書を読むという手もある。インターネット上にたくさんあります。

 
Zhunko:

OOPはオブジェクトを見つけるところから始まります。オブジェクトがなければ、OOPは存在しない。

通常、オブジェクトは何らかのリソース、データである。

書いて、他の人がどう書くかを見るだけでいいんです。そうすれば、自分自身で解決することができます。教科書を読むという手もある。インターネット上にたくさんあります。


教科書を何冊か推薦してください.あなたの考える最も簡単で便利なもの ...
 
VOLDEMAR:

チュートリアルのカップルを推薦してください ...あなたの考える最も簡単で便利なもの ...

グレイディ・ブッフ"オブジェクト指向の解析と設計 C++の応用例付き」。

Ire Paul(アイラ・ポール)と表記されることもある「C++によるオブジェクト指向プログラミング」。

 

1) OOPとは関係ありませんが、取引操作のエラーハンドラ(OrderSend(),OrderDelete(),OrderModify())を追加して欲しいのですが・・・。

OOPに対応させるために、仮想クラスメソッドとする(子孫クラスでオーバーライドするため、他のコードの処理を追加する)。

2) 子クラスで現在とは異なる動作をする可能性のあるすべてのクラスメソッドを仮想 化する。

第一候補はopenorders() です。

デメリットは、仮想メソッドでは、パラメータの数や種類を変更することができないことです。

プラス面では、「古い」BuySelBuyStop などは、「新しい」(子クラスで変更された)openorders() を呼び出すことができるようになることです。

3)一度にもっと素敵な名前をつけましょう。openordersの 代わりにopenOrdersを 使うなど。

4)何かを呼ぶための用語であれば、似たような用語を使用する。

売り=SELL であれば、SellまたはSELLと呼ぶ(例:SelStopではなく SellStop)

5) クラスからすべての定数(500 など)を削除する必要があります。

変数から取り出したり、メソッドのパラメータとして設定するようにしましょう。

今はopenorders()に埋め込まれた500個ほどのことを覚えていますが、後でそれを忘れたり、これらのクラスを使ってたくさんのフクロウを書いたりして、何かを変更することが難しくなります。

一番直すのが難しいのは、アーキテクチャーのエラーです。

そして、今作っている骨格です(単なる練習でないなら)。

6)すべてを1つのクラスにまとめない。

clOrder クラスを作り、 SetSL,CloseOrder,GetSL,GetProfit,SetTP,GetTPなどをくっつけて ください。

そしてclTrade クラスに、注文の配列/リスト、シンボル、シンボルのプロパティ(TICKETSIZEPOINTTICKETVALUE、MINLOT、MAXLOT、STOPSTEP、LOTSTEP、LOTSIZEなど )を追加してください。

AskとBidを(シンボルのプロパティとして)アタッチする場合、OnTick() でそれらをリフレッシュすることを忘れないでください。

RefreshRates() に、МТ変数のAskとBidのプロパティを更新した後に呼び出すようにバインドする(誰が開いて誰が閉じたかという注文の状態もチェックしている)。閉じたものは注文リストから削除されます)。

スケジュール(まずクラスを作る)、トレーリングストップ(これも別にクラスを作る)を追加することができます。

追記:週末に全部やりましたが(トレード用のライブラリを作りました)、今回はクラスを使わないことにしました(構造体と構造体の配列とそれを扱う関数だけです)。

毎日のスケジュールもあります(アルプス・オン・ゴールドは毎日0:00から1:00までが休憩時間なので)。取引終了2分前になると、スケジュールチェッカーはすべての取引を終了し、すべての注文をキャンセルします。

そして、取引の最後の1時間は、負けている取引を閉じ、注文をキャンセルし、利益のある取引をトリルします。トレーリングストップも作りました。一種類だが、パラメータが異なるため、異なる記号に適合する。

シンボル(独自のフィールドを持つ)、注文(独自のフィールドを持つ)、スケジュール(独自のフィールドを持つ)、シンボルを参照する独自のフィールドを持つエキスパートアドバイザー(magikなど)、注文リストとスケジュールリストを持つ、という図式です。

階層の最上位はアドバイザーのリスト です(シンボルとマジックの組み合わせはユニークでなければなりません)。

 
VOLDEMAR:

おすすめのチュートリアルを教えてください ...あなたの意見で最もシンプルで便利なのは・・・。

CodeBaseにOOPで書かれた例が出てくるようになった。例えばVOLDEMARから))))

実は、あなたのhttps://www.mql5.com/ru/code/11159 が、私のトレードライブラリを構造用に書き直すきっかけになったんです。

私はクラスについては待つことにしました。MQLでクラスを使う意味がわかりません

 
よくわからないのですが、今、標準の Tradeクラスを使うことは可能なのでしょうか?
それともMQL5のみ標準搭載で、新しいMetaEditorではそこから引き継がれただけなのでしょうか?
 
EverAlex:

CodeBaseにOOPで書かれた例が出てくるようになった。例えばVOLDEMARから))))

実は、あなたのhttps://www.mql5.com/ru/code/11159 がきっかけで、構造物用のトレードライブラリを書き換えることになりました。

私はクラスについては待つことにしました。これまでのところ、MQLでクラスを使用する意味がわかりません。


はい、書きましたが、関数をクラスに移す以外は、まだ何も理解していません。
 
VOLDEMAR:

はい、書きました。でも、関数をクラスに移すこと以外は、まだ何も理解していないんです。

3(+1) OOPの原則。

1)カプセル化 つまり、変数や擬似変数(「オブジェクト・プロパティ」または単に「プロパティ」と呼ばれる)をオブジェクト自体に格納することです。すなわち、クラスが正しく宣言されていれば、そのデータを外部から変更することはできない。

クラス自体の関数(「クラスメソッド」または単に「メソッド」と呼ばれる)を使用することによってのみ可能です。変数に値を代入するだけでなく、それらのフィールドの変化に関連した何らかのアクションを実行するために必要です。

そしてこれが、関数を移植するよりも、MQLにOOPを導入することの主な(私の考える)有用性です(私のトレードライブラリの関数は、パラメータの1つとしてEAのインデックスを受け取り、その注文の配列を含む、選択したEAで動作します)。

あなたが作ったクラスのデータに(ソースコードがなければ)誰も入り込めないし、あなたのコードにエラーがあると文句を言われることもない。

2)継承 祖先クラスが作られると、祖先クラスのすべてのフィールドとメソッドを継承します(祖先クラスでは見ることができないフィールドとメソッドのプライベート 型がありますが、今は省略します)。

そして、このオブジェクトの設計段階では、クラスがどのように使用されるか、どのようなフィールドを含むか、子孫クラスでどのように見えるようにするかなど、アーキテクチャを明確に考える必要があります。

強力なシステムやクラスライブラリで、個人的には貿易業務では見かけないようなタスクに使われています。でも、もしかしたら誰かに必要とされるかもしれない。例えば、異なるトレーリングストップを持つ子孫クラスを作ることができます。

そのため、メソッド内に定数は存在せず、すべて適切なメソッド(通常は.Set で始まる)を使って外部から設定するか、メソッドのパラメータとして直接設定しなければならないのです。それが、あなたの500という ことです。

3)ポリモルフィズム 数回上に書いたことですが、子孫クラスの関数 openorders() でリモデルした場合、古い Buy() 関数を自由に呼び出すことができます。

ポリモーフィズムの例として、幾何学図形の面積を異なる形状で計算することが挙げられます。

円の場合はある方法で、四角の場合は別の方法で計算されます。しかし、いずれにせよ、 Figura.GetSquare() を呼び出すことで、ベースクラスから継承した特定の 形状の面積を得ることができます(Square() を宣言するのを忘れていなければですが)。

ベースクラスのアーキテクチャを作成するためには、ここでも何らかの資格が必要です。例えば、Square()virtualと 宣言し忘れると、Squareを 汎用的に呼び出すことができなくなります(呼び出すたびにクラスの型を確認し、Squareの 実装を正確に呼び出さなければならなくなります)。

コンストラクタ以外のすべてのメソッドを仮想化することを推奨する人もいます(私は、クラスを作成するときに、そのクラスがどのように成長できるかの地平を見ることができない場合は、同じ見解をとります)。要は、デストラクタも仮想でなければならない。


更新しました。

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

4)抽象化 (同志からの要求ですが、私がOOPを勉強したとき(1990年代)、それは原則とは考えられていませんでした(実際には-最初の3つから派生しただけのため)、記事(下記のリンク参照)にはそれについて書かれていますが、記事のタイトルにはなく、3つしかありません)。

実際には、「空の」基底クラス(メソッドが宣言されているが、何もしない)を作成することになります。言語によっては、メソッドに抽象的な マークをつけることができます。 これは、子孫クラスでは必ず オーバーラップさせなければならない(つまり、何かをするメソッドが追加される)ことを意味します。

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

追記:あまり詳しいことは書かずに、こちらで 簡単に読むことができます。


PPS:気を悪くしないでほしいのですが、Workで「トレードライブラリを書いてください」とお願いしたところ、「持っていて使っている」と答えた人は1人だけでした。

5人のMQLプログラマーが(Skypeで)、何が含まれるべきか見当もつかず、必要な関数をあるフクロウから別のフクロウにコピーペーストしていると言っていました。彼らは、何も変更せず、数ミリ秒以上実行されないコード断片の間に RefreshRates() を貼り付けることさえあるのです。そして、その後のコードは、変更されたAskとBid、そして(多分)注文の種類に依存しません。

したがって、これまで他のプログラミング言語でOOPを扱ったことがないMQLプログラマーにとって、MQLのOOPは役に立たないでしょう。せいぜい、外部からの変更からデータを隠す程度です(これも悪くはないのですが)。

 
EverAlex:

3)OOPの3原則。

1)カプセル化 すなわち、変数、擬似変数(「オブジェクトプロパティ」または単に「プロパティ」と呼ばれる)をオブジェクト自体に格納することです。つまり、クラスが正しく宣言されていれば、そのデータは

2)継承 祖先クラスが作られると、祖先クラスのすべてのフィールドとメソッドを継承します(祖先クラスからは見えないフィールドとメソッドのプライベート 型がありますが、ここではとりあえず省略します)。

3)ポリモルフィズム 数個上の記事で書いたこと - 子クラスで関数 openorders() を改造した場合、古い関数 Buy() などを安全に呼び出すことができます。

ポリモーフィズムの例として、幾何学図形の面積を様々な形状で計算することが挙げられる。

円の場合はある方法で、四角の場合は別の方法で計算されます。しかし、いずれにせよ、 Figura.GetSquare() を呼び出せば、ベースクラスから継承した特定の 形状の面積を得ることができます(Square() を宣言し忘れていない限り)。

4番目はどこだ!?アブストラクトはどこだ!忘れ去られるのは当然 :-(
 
Zhunko:
4番目はどこだ!?アブストラクトはどこだ!忘れ去られるのは当然 :-(


追加する。