Perché nessuno ha deciso di discutere di "programmazione procedurale con puntatori di funzione vs. programmazione procedurale senza puntatori di funzione"?
Se non ci sono molte opzioni, puoi cavartela con if e swipe.
Il punto è nel lavoro che deve essere fatto per comprimere in codice le soluzioni di un numero enorme di compiti. La questione riguarda l'universalizzazione del codice, dove qualsiasi sintassi e shell aggiuntiva è semplicemente distruttiva. È un lavoro duro, ma ti libera di tutto il superfluo e ti permette di evolvere, raggiungendo sempre nuove altezze.
Реter Konow: 1. Дело в работе которую нужно провести чтобы сжать в коде решения огромного количества задач.
2. Il punto è l'universalizzazione del codice, in cui qualsiasi tecnica di sintassi e shell aggiuntiva è semplicemente distruttiva. È un lavoro duro, ma si sbarazza di tutto il superfluo e ti permette di evolvere sempre raggiungendo nuove vette.
1. Perché fare il lavoro quando puoi renderlo facile e semplice? Perché renderlo difficile quando si può renderlo facile?
2. Se si usa OOP, l'universalizzazione non è distruttiva, ma diventa una possibilità naturale che non grava su nulla.
1. Perché fare il lavoro quando può essere fatto facilmente e senza problemi? Perché fare qualcosa che può essere fatto facilmente quando è difficile?
2. Se si usa OOP, allora l'universalizzazione non è rovinosa, ma diventa una possibilità naturale che non grava su nulla.
Possiamo continuare a lungo con questo argomento. Utilizzando l'esempio di un compito di 100 tracce, ho mostrato il mio atteggiamento verso questo metodo di soluzione. Credo che i compiti stupidi non debbano essere risolti ma aggiustati. Se l'OOP aiuta coloro che sono più deboli nel sollevare e risolvere correttamente i compiti, che li aiuti. Ma per le persone che ottimizzano i compiti prima di iniziare a risolverli, OOP può semplicemente non essere necessaria.
Potremmo continuare all'infinito con questo argomento. Utilizzando l'esempio di un compito di 100 tracce, ho mostrato il mio atteggiamento verso questo metodo di soluzione. Credo che i compiti stupidi non debbano essere risolti ma aggiustati. Se l'OOP aiuta coloro che sono più deboli nel sollevare e risolvere correttamente i compiti, che li aiuti. Ma per le persone che ottimizzano i compiti prima di iniziare a risolverli, OOP può semplicemente non essere necessaria.
Non hai codificato molto (probabilmente), OOP è come una boccata d'aria.
La maggior parte delle persone codifica non per interesse o autosviluppo, è il loro lavoro, ed è il risultato che conta.
Non è così conveniente, ma in termini di capacità di velocità, si può andare avanti solo con i puntatori.
E la convenienza è un concetto relativo.
Dmitry, ovviamente usare OOP riduce un po' le prestazioni. Ma sono frazioni di percentuale.
Ma come OOP aumenta le prestazioni di un programmatore!
Ecco un piccolo esempio da uno dei miei progetti, è tagliato per la percezione, ma in realtà ci sono molte altre cose prese in considerazione.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
Per esempio, prendiamo .NET, poiché tutte le API sono costituite da classi.
Mi piace molto il paradigma .NET. A proposito, c'è un grande terminale cAlgo, si può scrivere direttamente in Visual Studio in C#
Dimitri, ovviamente usare OOP riduce un po' le prestazioni. Ma sono frazioni di percentuale.
Se il numero di varianti è piccolo, lo rallenterà, ma se ci sono troppe varianti, sarà un vantaggio.
La cosa più importante è che il numero di varianti in OOP non influisce sulle prestazioni. E nella programmazione procedurale, c'è un tetto sopra la tua testa.
È chiaro che qualsiasi compito può essere risolto sia in stile OOP, con l'assegnazione di interfacce, la costruzione della gerarchia di ereditarietà, la dichiarazione di funzioni virtuali, sia in puro stile procedurale - si può anche infilare tutto in una funzione enorme.
La questione è nella convenienza e nell'efficienza del supporto.
In MT - il posto più adatto all'OOP è il sistema degli ordini. Personalmente, ho interfacce virtuali per "posizione" e "componenti di posizione". "Posizione" è un insieme di ordini in MT4 o un insieme di posizioni in MT5. "Componente della posizione" è un ordine individuale o una posizione MT5 individuale (hedge o netting).
Ecco il file di interfaccia attuale(Retag Konow, si può apprezzare il numero di commenti rispetto alla quantità di codice, e li aggiungo periodicamente quando incontro che non ricordo alcune sottigliezze. Per esempio, dimentico regolarmente quali oggetti reali costituiscono un "componente di posizione". Non ho bisogno di ricordarlo - l'Expert Advisor lavora con i componenti secondo l'interfaccia, e quello che c'è dietro quell'interfaccia in realtà non ha importanza. Ma, devo ritornarci durante la modifica - ecco perché ho bisogno molto spesso del primo commento in questo file):
// СTradePositionI переносимый интерфейс торговой позиции // Позиция состоит из компонент-наследников интерфейса CTradePosComponentI// // Реально для МТ4 имплементацией интерфейса является объект CMT4PositionInfo, для МТ5 - объект CMT5PositionInfo// CMT4PositionInfo представляет из себя массив объектов CMT4OrderInfo, наследников интерфейса CTradePosComponentI.// Фактически это массив МТ4-ордеров.// CMT5PositionInfo представляет из себя массив объектов CMT5PositionInfoCore, наследников интерфейса CTradePosComponentI.// Объект CMT5PositionInfoCore не имеет прямого аналога в МТ5-терминах, это два массива ордеров и сделок, а также структура данных,// имеющуая идентификатор позиции (m_lPosID или POSITION_IDENTIFIER), тикет магик, вид позиции, и так далее, по аналогии с МТ4-ордером,// фактически, массивы ордеров и сделок - это аналоги ордеров и сделок обычной неттинговой МТ5-позиции, а структура данных - относится// к хеджевой позиции, и имеет аналог МТ4-ордера. //// Реально при запросе у позиции компоненты CTradePosComponentI в МТ4 мы получаем указатель на ордер (класс CMT4OrderInfo),// а в МТ5 - на ядро позиции (класс CMT5PositionInfoCore) #include <MyLib\DebugOrRelease\DebugSupport.mqh>
#include <MyLib\Common\MyObject.mqh>
#include <MyLib\Common\CurSymEnum.mq5>
#include <MyLib\Common\TrendEnums.mqh>
#include <MyLib\Trade\TradePosComponentI.mqh>
class CTradePositionI: public CMyObject
{
public:
void CTradePositionI() { SetMyObjectType(MOT_TRADE_POSITION_I); };
virtualvoid ~CTradePositionI() {};
// Выбор существующей позиции. // Указывается магик и символ, по которому выбираются действующие ордера.// Если ulMagic = 0 - выбираются все позиции по всем магикам.// Если ECurrencySymbol = CS_UNKNOWN - выбираются все позиции по всем символам// Если ECurrencySymbol = CS_CURRENT - запрашивается функция Symbol(), и выбираются все позиции по этому символу// Возвращает число компонент позиции внутри позиции (может быть нулевым если позиции нет) или WRONG_VALUE в случае ошибок// Каждая фабрика (наследник CEAPartsFactoryT) имеет одну позицию, которая на каждом CEAPartsFactoryT::OnRefresh()// обновляется в соответствии с магиком и рабочим символом фабрики. virtualint Select(ulong ulMagic = 0,ECurrencySymbol csSymbol = CS_CURRENT) = 0;
virtualuint GetTotalComponents() const = 0; // Получение общего числа компонентvirtualuint GetNumOfComponentsOnDirection(ENUM_POSITION_TYPE etDirection) const = 0; // Получение числа компонент указанного направления (если tdDirection = TD_FLAT - то всех компонент) и интерфейс отдельной компонентыvirtual CTradePosComponentI* GetComponent(uint uiComponentIdx) const = 0;
// Расширенный интерфейс// Функция исследует позицию, и возвращает ее направление:// Если все компоненты - лонги, то вверх.// Если все компоненты - шорты, то вниз.// Если компонент нет - то флет. // Если компоненты обоих типов, то смотрим на флаг bFlatIfBoth. // Если этот флаг установлен - то возвращаем флет.// Если этот флаг сброшен - то смотрим на флаг bConsiderVolume.// Если этот флаг установлен - то сравниваем общие объемы лонгов и шортов. Если сброшен - сравниваем количество лонгов и шортов.// Каких позиций (или объемов) больше - то направление и возвращаем. // Если позиций (или объемов) одинаково - возвращаем флет.// NOTE !!! Функция не проверяет магик и символ компонент !virtual ETrendDirection GetDirection(bool bFlatIfBoth = true,bool bConsiderVolume = true) const = 0;
// Функция ищет внутри позиции компоненту с указанным тикетом. // В случае, если ее нет - возвращается false.// Если компонента найдена - возвращается true, и uiComponentIdx устанавливается на индекс компоненты внутри позиции.virtualbool FindComponentByTicket(long lTicket,uint &uiComponentIdx) const = 0;
};
Il file per l'interfaccia del componente commerciale è il seguente (l'ho già dato sopra, ma lo ripeto:
// СTradePositionComponentI переносимый интерфейс компоненты торговой позиции #include <MyLib\DebugOrRelease\DebugSupport.mqh>
#include <MyLib\Common\MyObject.mqh>
#include <MyLib\Common\CurSymEnum.mq5>
#include <MyLib\Common\EnumsMT5ForMT4.mqh>
// CTradePosComponentI - компонента позиции. Имеет определенный магик, определенный символ, определенный тикет. // Для МТ4 компонента позиции - это МТ4-ордер.// Для МТ5 компонента позиции - это МТ5-позиция (одна для каждого символа при неттинге, и много для каждого символа при хедже).class CTradePosComponentI: public CMyObject
{
public:
void CTradePosComponentI() { SetMyObjectType(MOT_TRADEPOS_COMPONENT_I); };
virtualvoid ~CTradePosComponentI() {};
// Основной интерфейсvirtuallong GetTPCTicket() const = 0;
virtuallong GetTPCMagic() const = 0;
virtual ECurrencySymbol GetTPCSymbol() const = 0;
virtualENUM_POSITION_TYPE GetTPCType() const = 0;
virtualdatetime GetTPCOpenTime() const = 0;
virtualdouble GetTPCVolume() const = 0;
virtualdouble GetTPCOpenPrice() const = 0;
virtualdouble GetTPCStopLoss() const = 0;
virtualdouble GetTPCTakeProfit() const = 0;
virtualstring GetTPCCommentary() const = 0;
virtualbool IsTPCInUnloss() const { if(GetTPCStopLoss() <= 0 || GetTPCStopLoss() == EMPTY_VALUE) return(false); if(GetTPCType() == POSITION_TYPE_BUY) { if(GetTPCStopLoss() >= GetTPCOpenPrice()) return(true); } else { if(GetTPCStopLoss() <= GetTPCOpenPrice())return(true); }; return (false); };
virtualdouble GetTPDistance() const { if(GetTPCTakeProfit() == 0 || GetTPCTakeProfit() == EMPTY_VALUE) return(EMPTY_VALUE); if(GetTPCType() == POSITION_TYPE_BUY) return(GetTPCTakeProfit() - GetTPCOpenPrice()); return(GetTPCOpenPrice() - GetTPCTakeProfit()); };
virtualdouble GetSLDistance() const { if(GetTPCStopLoss() == 0 || GetTPCStopLoss() == EMPTY_VALUE) return(EMPTY_VALUE); if(GetTPCType() == POSITION_TYPE_BUY) return(GetTPCOpenPrice()- GetTPCStopLoss()); return(GetTPCStopLoss() - GetTPCOpenPrice()); };
};
class CHistoryPosComponentI: public CTradePosComponentI
{
public:
void CHistoryPosComponentI() { SetMyObjectType(MOT_HISTORYPOS_COMPONENT_I); };
virtualvoid ~CHistoryPosComponentI() {};
virtualdatetime GetTPCCloseTime() const = 0;
virtualdouble GetTPCClosePrice() const = 0;
virtualdouble GetTPCProfit() const = 0; // Возвращает профит по исторической позицииvirtualbool IsProfitClosePrice() const = 0; // Возвращает true, если цена зарытия отличается от цены открытия в прибыльную сторону // Возвращает профит исторической позиции для случая, когда бы ход цены (в сторону профита) был бы равен dPriceMove, а лот был бы единичным.// Функция используется для расчета лота для такой же позиции с нужным ходом цены // Рекомендуется отнимать от цены двойной спред.virtualdouble CalculateOneLotProfit(double dPriceMove) const = 0;
};
In base a queste interfacce - ho implementato sia il sistema di ordini MT4 che MT5 per ordini reali e storici.
L'Expert Advisor che richiede una posizione riceve questa interfaccia e non deve tenere conto della differenza tra gli ordini MT4 e MT5. E se viene aggiunto un nuovo tipo di ordine o viene cambiato l'ordine di lavorare con essi - non cambierà nulla per l'Expert Advisor, solo la nuova classe del tipo di ordine verrà aggiunta, e supporterà anche questa interfaccia.
Il sistema ha avuto molto senso quando sono stati introdotti i conti coperti. Gli esperti non sono cambiati affatto.
Reg Konow, come ti occupi della differenza dei tipi di ordine in MT4 e MT5?
Se viene introdotto un nuovo tipo di conto (oltre alla copertura e al netting) - quali cambiamenti dovranno essere fatti, e nello stesso posto?
La mia opinione è che se ti ricordi tutto il tuo codice alla lettera, e puoi facilmente dire perché questa o quella linea nel tuo codice è stata scritta un anno fa - allora è vero, tutti questi miglioramenti OOP sono solo gesti inutili.
L'OOP è necessaria proprio quando non si ricorda tutto quando si modifica il codice - l'OOP permette di isolare i blocchi l'uno dall'altro, limitare l'insieme delle entità disponibili in qualsiasi momento in un posto particolare del programma.
1. È chiaro che qualsiasi compito può essere risolto sia in stile OOP, con l'assegnazione di interfacce, la costruzione della gerarchia di ereditarietà, la dichiarazione di funzioni virtuali, sia in puro stile procedurale - possiamo anche mettere tutto in una funzione enorme.
La questione è nella convenienza e nell'efficienza del supporto.
2. In MT - il posto più adatto all'OOP è il sistema degli ordini. Personalmente, ho interfacce virtuali "posizioni" e "componenti di posizione". "Posizione" è un insieme di ordini in MT4 o un insieme di posizioni in MT5. "Componente della posizione" è un ordine individuale o una posizione MT5 individuale (con copertura o netting).
3. Ecco il file di interfaccia attuale(Retag Konow, si può apprezzare il numero di commenti rispetto alla quantità di codice, e li aggiungo periodicamente quando incontro che non ricordo alcune sottigliezze. Per esempio, dimentico regolarmente quali oggetti reali costituiscono un "componente di posizione". Non ho bisogno di ricordarlo - l'Expert Advisor lavora con i componenti secondo l'interfaccia, e quello che c'è dietro quell'interfaccia in realtà non ha importanza. Ma, devo ritornarci durante la modifica - ecco perché ho bisogno molto spesso del primo commento in questo file):
Il file per l'interfaccia del componente commerciale è il seguente (l'ho già dato sopra, ma lo ripeto:
In base a queste interfacce - ho implementato sia il sistema di ordini MT4 che MT5 per ordini reali e storici.
L'Expert Advisor che richiede una posizione riceve questa interfaccia e non deve tenere conto della differenza tra gli ordini MT4 e MT5. E se viene aggiunto un nuovo tipo di ordine o viene cambiato l'ordine di lavoro con essi - non cambierà nulla per l'Expert Advisor, solo un nuovo tipo di ordine verrà aggiunto, e supporterà anche questa interfaccia.
Il sistema si è dimostrato molto ragionevole, quando sono stati introdotti i conti di copertura. Gli esperti non sono cambiati affatto da allora.
4. Reg Konow, come ti occupi della differenza dei tipi di ordine in MT4 e MT5?
Se viene introdotto un nuovo tipo di conto (oltre alla copertura e al netting) - quali cambiamenti dovranno essere fatti, e nello stesso posto?
Penso che se ti ricordi tutto il tuo codice alla lettera, e puoi facilmente dire perché questa o quella linea è stata scritta un anno fa - allora tutti questi miglioratori OOP sono solo gesti inutili.
L'OOP è necessaria proprio quando non si ricorda tutto quando si modifica il codice - l'OOP permette di isolare i blocchi l'uno dall'altro per limitare l'insieme delle entità disponibili in un dato momento in un posto particolare del programma.
1. 1. Sono assolutamente d'accordo. L'unica differenza è nell'efficacia di risolvere i compiti in un modo o nell'altro.
2. Non ho lavorato molto con il sistema degli ordini e non vedo alcun problema tecnico nella sua costruzione. Forse ci sono, ma abbiamo bisogno di un compito concreto e allora sarà chiaro quanto efficacemente posso risolverlo senza l'OOP.
3. Dal mio punto di vista, l'esempio di codice dato è semplicemente terribile dal punto di vista della leggibilità. Non c'è da stupirsi che siano necessari così tanti commenti e che si dimentichi il suo contenuto. Scusa, ma questa è la mia prima impressione soggettiva. È semplicemente inquietante.
Ecco un esempio di leggibilità del mio codice - la funzione che definisce il colore dell'elemento di un controllo:
Come potete vedere, i commenti sono quasi inutili qui. Tutto il mio codice è scritto in questo stile. Quindi la conosco perfettamente e la ricordo a prescindere dalle dimensioni.
Secondo me, c'è qualche difetto nel vostro sistema di risoluzione dei problemi. Il problema stesso dovrebbe essere chiaro e preciso, e quindi anche la sua soluzione. Se la soluzione è nebulosa e definita dalle parole "Il sistema si è dimostrato molto ragionevole" (come può essere ragionevole in 270 Kb di codice?!), significa che l'autore ha una comprensione approssimativa di come funziona il suo sistema. E sono terribili gli artifizi di sintassi e le entità inutili nella soluzione che gli impediscono di capirla fino in fondo.
Affinché una soluzione sia efficace, le entità inutili devono essere tagliate e il problema deve essere visto perfettamente.
Sì, queste unità hanno entrambi. Ma credetemi - sono compressi al massimo e versatili, perché risolvono una vasta gamma di problemi.
Se non ci sono molte opzioni, puoi cavartela con if e swipe.
Perché nessuno ha deciso di discutere di "programmazione procedurale con puntatori di funzione vs. programmazione procedurale senza puntatori di funzione"?
Se non ci sono molte opzioni, puoi cavartela con if e swipe.
Реter Konow:
1. Дело в работе которую нужно провести чтобы сжать в коде решения огромного количества задач.
2. Il punto è l'universalizzazione del codice, in cui qualsiasi tecnica di sintassi e shell aggiuntiva è semplicemente distruttiva. È un lavoro duro, ma si sbarazza di tutto il superfluo e ti permette di evolvere sempre raggiungendo nuove vette.
1. Perché fare il lavoro quando puoi renderlo facile e semplice? Perché renderlo difficile quando si può renderlo facile?
2. Se si usa OOP, l'universalizzazione non è distruttiva, ma diventa una possibilità naturale che non grava su nulla.
1. Perché fare il lavoro quando può essere fatto facilmente e senza problemi? Perché fare qualcosa che può essere fatto facilmente quando è difficile?
2. Se si usa OOP, allora l'universalizzazione non è rovinosa, ma diventa una possibilità naturale che non grava su nulla.
Possiamo continuare a lungo con questo argomento. Utilizzando l'esempio di un compito di 100 tracce, ho mostrato il mio atteggiamento verso questo metodo di soluzione. Credo che i compiti stupidi non debbano essere risolti ma aggiustati. Se l'OOP aiuta coloro che sono più deboli nel sollevare e risolvere correttamente i compiti, che li aiuti. Ma per le persone che ottimizzano i compiti prima di iniziare a risolverli, OOP può semplicemente non essere necessaria.
Potremmo continuare all'infinito con questo argomento. Utilizzando l'esempio di un compito di 100 tracce, ho mostrato il mio atteggiamento verso questo metodo di soluzione. Credo che i compiti stupidi non debbano essere risolti ma aggiustati. Se l'OOP aiuta coloro che sono più deboli nel sollevare e risolvere correttamente i compiti, che li aiuti. Ma per le persone che ottimizzano i compiti prima di iniziare a risolverli, OOP può semplicemente non essere necessaria.
Non hai codificato molto (probabilmente), OOP è come una boccata d'aria.
La maggior parte delle persone codifica non per interesse o autosviluppo, è il loro lavoro, ed è il risultato che conta.
Non è così conveniente, ma in termini di capacità di velocità, si può andare avanti solo con i puntatori.
E la convenienza è un concetto relativo.
Dmitry, ovviamente usare OOP riduce un po' le prestazioni. Ma sono frazioni di percentuale.
Ma come OOP aumenta le prestazioni di un programmatore!
Ecco un piccolo esempio da uno dei miei progetti, è tagliato per la percezione, ma in realtà ci sono molte altre cose prese in considerazione.
Per esempio, prendiamo .NET, poiché tutte le API sono costituite da classi.
Mi piace molto il paradigma .NET. A proposito, c'è un grande terminale cAlgo, si può scrivere direttamente in Visual Studio in C#
Dimitri, ovviamente usare OOP riduce un po' le prestazioni. Ma sono frazioni di percentuale.
Se il numero di varianti è piccolo, lo rallenterà, ma se ci sono troppe varianti, sarà un vantaggio.
La cosa più importante è che il numero di varianti in OOP non influisce sulle prestazioni. E nella programmazione procedurale, c'è un tetto sopra la tua testa.
Beh, hai fatto un casino...
È chiaro che qualsiasi compito può essere risolto sia in stile OOP, con l'assegnazione di interfacce, la costruzione della gerarchia di ereditarietà, la dichiarazione di funzioni virtuali, sia in puro stile procedurale - si può anche infilare tutto in una funzione enorme.
La questione è nella convenienza e nell'efficienza del supporto.
In MT - il posto più adatto all'OOP è il sistema degli ordini. Personalmente, ho interfacce virtuali per "posizione" e "componenti di posizione". "Posizione" è un insieme di ordini in MT4 o un insieme di posizioni in MT5. "Componente della posizione" è un ordine individuale o una posizione MT5 individuale (hedge o netting).
Ecco il file di interfaccia attuale(Retag Konow, si può apprezzare il numero di commenti rispetto alla quantità di codice, e li aggiungo periodicamente quando incontro che non ricordo alcune sottigliezze. Per esempio, dimentico regolarmente quali oggetti reali costituiscono un "componente di posizione". Non ho bisogno di ricordarlo - l'Expert Advisor lavora con i componenti secondo l'interfaccia, e quello che c'è dietro quell'interfaccia in realtà non ha importanza. Ma, devo ritornarci durante la modifica - ecco perché ho bisogno molto spesso del primo commento in questo file):
Il file per l'interfaccia del componente commerciale è il seguente (l'ho già dato sopra, ma lo ripeto:
In base a queste interfacce - ho implementato sia il sistema di ordini MT4 che MT5 per ordini reali e storici.
L'Expert Advisor che richiede una posizione riceve questa interfaccia e non deve tenere conto della differenza tra gli ordini MT4 e MT5. E se viene aggiunto un nuovo tipo di ordine o viene cambiato l'ordine di lavorare con essi - non cambierà nulla per l'Expert Advisor, solo la nuova classe del tipo di ordine verrà aggiunta, e supporterà anche questa interfaccia.
Il sistema ha avuto molto senso quando sono stati introdotti i conti coperti. Gli esperti non sono cambiati affatto.
Reg Konow, come ti occupi della differenza dei tipi di ordine in MT4 e MT5?
Se viene introdotto un nuovo tipo di conto (oltre alla copertura e al netting) - quali cambiamenti dovranno essere fatti, e nello stesso posto?
La mia opinione è che se ti ricordi tutto il tuo codice alla lettera, e puoi facilmente dire perché questa o quella linea nel tuo codice è stata scritta un anno fa - allora è vero, tutti questi miglioramenti OOP sono solo gesti inutili.
L'OOP è necessaria proprio quando non si ricorda tutto quando si modifica il codice - l'OOP permette di isolare i blocchi l'uno dall'altro, limitare l'insieme delle entità disponibili in qualsiasi momento in un posto particolare del programma.
Beh, hai fatto un casino...
1. È chiaro che qualsiasi compito può essere risolto sia in stile OOP, con l'assegnazione di interfacce, la costruzione della gerarchia di ereditarietà, la dichiarazione di funzioni virtuali, sia in puro stile procedurale - possiamo anche mettere tutto in una funzione enorme.
La questione è nella convenienza e nell'efficienza del supporto.
2. In MT - il posto più adatto all'OOP è il sistema degli ordini. Personalmente, ho interfacce virtuali "posizioni" e "componenti di posizione". "Posizione" è un insieme di ordini in MT4 o un insieme di posizioni in MT5. "Componente della posizione" è un ordine individuale o una posizione MT5 individuale (con copertura o netting).
3. Ecco il file di interfaccia attuale(Retag Konow, si può apprezzare il numero di commenti rispetto alla quantità di codice, e li aggiungo periodicamente quando incontro che non ricordo alcune sottigliezze. Per esempio, dimentico regolarmente quali oggetti reali costituiscono un "componente di posizione". Non ho bisogno di ricordarlo - l'Expert Advisor lavora con i componenti secondo l'interfaccia, e quello che c'è dietro quell'interfaccia in realtà non ha importanza. Ma, devo ritornarci durante la modifica - ecco perché ho bisogno molto spesso del primo commento in questo file):
Il file per l'interfaccia del componente commerciale è il seguente (l'ho già dato sopra, ma lo ripeto:
In base a queste interfacce - ho implementato sia il sistema di ordini MT4 che MT5 per ordini reali e storici.
L'Expert Advisor che richiede una posizione riceve questa interfaccia e non deve tenere conto della differenza tra gli ordini MT4 e MT5. E se viene aggiunto un nuovo tipo di ordine o viene cambiato l'ordine di lavoro con essi - non cambierà nulla per l'Expert Advisor, solo un nuovo tipo di ordine verrà aggiunto, e supporterà anche questa interfaccia.
Il sistema si è dimostrato molto ragionevole, quando sono stati introdotti i conti di copertura. Gli esperti non sono cambiati affatto da allora.
4. Reg Konow, come ti occupi della differenza dei tipi di ordine in MT4 e MT5?
Se viene introdotto un nuovo tipo di conto (oltre alla copertura e al netting) - quali cambiamenti dovranno essere fatti, e nello stesso posto?
Penso che se ti ricordi tutto il tuo codice alla lettera, e puoi facilmente dire perché questa o quella linea è stata scritta un anno fa - allora tutti questi miglioratori OOP sono solo gesti inutili.
L'OOP è necessaria proprio quando non si ricorda tutto quando si modifica il codice - l'OOP permette di isolare i blocchi l'uno dall'altro per limitare l'insieme delle entità disponibili in un dato momento in un posto particolare del programma.
1. 1. Sono assolutamente d'accordo. L'unica differenza è nell'efficacia di risolvere i compiti in un modo o nell'altro.
2. Non ho lavorato molto con il sistema degli ordini e non vedo alcun problema tecnico nella sua costruzione. Forse ci sono, ma abbiamo bisogno di un compito concreto e allora sarà chiaro quanto efficacemente posso risolverlo senza l'OOP.
3. Dal mio punto di vista, l'esempio di codice dato è semplicemente terribile dal punto di vista della leggibilità. Non c'è da stupirsi che siano necessari così tanti commenti e che si dimentichi il suo contenuto. Scusa, ma questa è la mia prima impressione soggettiva. È semplicemente inquietante.
Ecco un esempio di leggibilità del mio codice - la funzione che definisce il colore dell'elemento di un controllo:
Come potete vedere, i commenti sono quasi inutili qui. Tutto il mio codice è scritto in questo stile. Quindi la conosco perfettamente e la ricordo a prescindere dalle dimensioni.
Secondo me, c'è qualche difetto nel vostro sistema di risoluzione dei problemi. Il problema stesso dovrebbe essere chiaro e preciso, e quindi anche la sua soluzione. Se la soluzione è nebulosa e definita dalle parole "Il sistema si è dimostrato molto ragionevole" (come può essere ragionevole in 270 Kb di codice?!), significa che l'autore ha una comprensione approssimativa di come funziona il suo sistema. E sono terribili gli artifizi di sintassi e le entità inutili nella soluzione che gli impediscono di capirla fino in fondo.
Affinché una soluzione sia efficace, le entità inutili devono essere tagliate e il problema deve essere visto perfettamente.