Spese generali per l'OLP - pagina 3

 
George Merts:

1. Per esempio, avete bisogno di un array di oggetti.

Puoi farlo proceduralmente, o puoi farlo basandoti su CArrayObj e CObjest. I problemi iniziano quando hai bisogno di cambiare il comportamento di, diciamo, aggiungere o rimuovere oggetti, o ordinarli. In OOP, il supporto per un array di puntatori vero e proprio e per lavorare con esso è racchiuso negli oggetti di base. Modificare gli oggetti discendenti che sono effettivamente contenuti nell'array non ha alcun effetto. In stile procedurale - modificando oggetti reali che sono effettivamente contenuti in un array - di solito colpisce molti più posti, almeno perché dobbiamo considerare i cambiamenti nella dimensione degli oggetti. Il che porterà molto più facilmente a degli errori.

2. Cross-platform - anche molto più comodo da organizzare in stile OOP. Quando sulla richiesta, diciamo, di una posizione commerciale - otteniamo un'interfaccia, e non importa su quale piattaforma lavoriamo - l'interfaccia offre funzioni virtuali, su cui è possibile ottenere tutti i dati su tutti gli ordini (per MT4) o posizioni (MT5), e, dal punto di vista degli esperti - non c'è differenza. L'Expert Advisor non ha bisogno di sapere su quale piattaforma lavora.

3. Bene, "finire nella programmazione procedurale" è "scrivere oggetti-procedure", cioè, la creazione di alcuni collegamenti tra dati e procedure, che rappresentano oggetti in OOP.

4. E poi abbiamo, diciamo, un certo numero di tipi di ordini, che hanno molto in comune. Sarebbe ragionevole fare un oggetto COrderInfo - che sarebbe l'oggetto base, e i suoi eredi rappresenterebbero diversi tipi di ordini. A quel punto, il processore commerciale (ho la classe CTradeProcessor) supporterà automaticamente esattamente quell'ordine, che gli è stato passato, da quelle procedure che sono richieste per elaborare quell'ordine.

5.È più facile catturare i bug dove c'è il minor numero di collegamenti incrociati. Questo è assicurato dall'incapsulamento e dal polimorfismo. Richiediamo l'interfaccia della posizione commerciale (CTradePositionI) e tutte le connessioni con le classi reali, che rappresentano questa posizione (CMT4PositionInfo,CMT5PositionInfo) sono fatte solo attraverso questa interfaccia, che contribuisce solo a una più facile correzione degli errori, che se lavoriamo direttamente con le funzioni reali, restituendo i dati della posizione commerciale.

1. Per quale motivo?

Perché la stessa funzione non può essere compilata su diverse piattaforme?

3. l'idea era di impacchettare il testo delle funzioni in base al tipo di struttura per rendere più conveniente riferirsi ad esse per analogia con il riferimento a una funzione come membro di una classe. In linea di principio, non è necessario creare alcun oggetto per questo scopo.

4. Sarebbe più ragionevole fare una sola funzione con le sue impostazioni, piuttosto che moltiplicare diversi oggetti e connessioni inutili attraverso le interfacce.

5. Inoltre, tutti questi collegamenti devono essere programmati e poi tracciati attraverso le interfacce e simili, dove i bug possono essere difficili da prendere. Questa occupazione è inutile e senza senso fin dall'inizio.

 
Andrei:

1. Per esempio, per cosa?

2. Perché la stessa funzione non può essere compilata su diverse piattaforme, in modo da non dover creare interfacce per essa?

Intendevo impacchettare il testo delle funzioni in base al tipo di struttura per un accesso più comodo, simile all'indirizzare una funzione come membro di una classe. In linea di principio, nessun oggetto deve essere creato a questo scopo.

4. È più intelligente fare una sola funzione con le impostazioni, invece di moltiplicare diversi oggetti e connessioni inutili attraverso le interfacce.

5. Inoltre, tutti questi collegamenti devono essere programmati e poi tracciati attraverso le interfacce e simili, dove i bug possono essere difficili da prendere. Questa occupazione è inutile e senza senso fin dall'inizio.

1. Bene, la classe CTradePosition è essenzialmente una lista di ordini aperti. E per loro, sarebbe molto utile avere un'interfaccia, una classe base e delle classi vere e proprie.

2. C'è solo un'interfaccia. Per tutte le piattaforme. E nel caso dell'OOP, non pensiamo veramente a dove stiamo lavorando. Non dobbiamo considerare cose dipendenti dalla piattaforma e dall'ordine.

E qual è la differenza tra oggetto e funzione in questo imballaggio? È quello che sto dicendo - è essenzialmente la stessa cosa. Nel caso di un oggetto - viene aggiunta anche una funzione costruttrice automatica, tuttavia, per default - è vuota.

4. Esattamente, proprio questa "funzione unica con impostazioni" è la fonte dei problemi. Perché di solito ci sono molte impostazioni. E non sono sparsi in diversi livelli della gerarchia di classe, ma concentrati proprio in questa funzione. Ma l'interfaccia permette di lasciare tutte le impostazioni non utilizzate in un dato contesto "fuori considerazione" - il che ha un ottimo effetto sulla comprensione del codice e sulle possibilità di errori e la loro individuazione. Questo è esattamente il vantaggio principale di OOP - tutte le funzionalità sono "sparse" in oggetti a diversi livelli di gerarchia e quando si lavora con questa o quella parte di esso - gli altri non interferiscono. In una singola funzione con impostazioni, invece, tutte le funzionalità sono sempre disponibili, anche se sono superflue. Questo è di solito una fonte di problemi semplicemente perché si può accidentalmente confondere le variabili. Lo svantaggio principale è che è molto più difficile rilevare gli errori in una tale funzione singola.

5. in ogni caso, questi collegamenti sono necessari e devono essere programmati - sono, infatti, le stesse impostazioni in una sola funzione. Per esempio, nel mio esempio - in una singola funzione abbiamo accesso alla differenza di piattaforme, diversi tipi di ordine, differenza nella rappresentazione della posizione - tutto questo deve essere preso in considerazione. E quando c'è un'interfaccia - tutto è "tagliato fuori" - solo ciò che è definito nell'interfaccia può essere preso in considerazione.

Questo è lo scopo dell'incapsulamento, per limitare l'accesso da un blocco di codice ad un altro blocco. Al contrario, voi suggerite di avere "una grande funzione universale con il massimo delle impostazioni", in modo che chiunque abbia accesso a questa funzione abbia il massimo delle possibilità. Questo, come dimostra la mia esperienza, è il modo sbagliato. Il modo giusto è al contrario, limitare l'utente il più possibile, se un blocco del programma ha bisogno della funzionalità di un altro blocco - dovrebbe avere solo questa funzionalità, e non un po' di più. Questa è la chiave per un codice più stabile e senza errori.

 
George Merts:

1. Bene, la classe CTradePosition è essenzialmente una lista di ordini aperti. Gli ordini possono essere diversi, e per loro è molto conveniente avere un'interfaccia, una classe base e delle vere e proprie classi.

E cosa c'è di sbagliato nel mantenere gli ordini in un array di strutture, o nel modo in cui è implementato in MT4?

 
Andrei:

Cosa c'è di sbagliato nel mantenere gli ordini in un array di strutture o come implementato in MT4?

Perché ogni utente ha troppi diritti e troppe informazioni inutili quando accede a questo array.

La cosa giusta da fare, secondo me, è dare all'utente solo la parte di funzionalità di cui ha bisogno - semplicemente usando un'interfaccia pre-concordata per accedere agli ordini.

 
George Merts:

Che ogni utente ha troppi diritti e troppe informazioni inutili quando accede a questo array.

La cosa giusta da fare, secondo me, è dare all'utente solo la parte di funzionalità di cui ha bisogno - semplicemente usando un'interfaccia pre-concordata per accedere agli ordini.

Potete creare il vostro tipo di dati per gli ordini, non c'è bisogno di interfacce, oggetti e altri artifizi inutili, che creano inutili bug e instabilità.

 
Andrei:

Potete creare il vostro tipo di dati per gli ordini, non c'è bisogno di alcuna interfaccia, oggetti e altri artifizi inutili, che creano inutili bug e instabilità.

La mia esperienza dimostra che è necessario.

Ho seguito questa strada circa cinque anni fa, allora su MT4. (Non perché non conoscessi l'OOP, ma perché ero troppo pigro per preoccuparmi delle interfacce e dell'ereditarietà, soprattutto perché a quel tempo MT4 e MT5 erano significativamente diversi in termini di implementazione MQL). Questo mi ha portato alla comprensione della sua fallacia. Questa non è "saggezza", ma una limitazione abbastanza ragionevole, una sorta di "infallibilità". Se vi ricordate sempre di cosa è responsabile ciascuna delle centinaia di variabili, non avete bisogno dell'incapsulamento. Non me lo ricordo, e preferisco avere il minor numero possibile di entità disponibili in ogni blocco di un programma.

Non appena MT4 è apparso OOP - ho immediatamente iniziato a tradurre tutti i miei sviluppi in una forma unica, basata su interfacce.

 
George Merts:

1. La mia pratica dimostra che, effettivamente, è necessario. Questo mi ha portato a capire la sua fallacia.

2. Non lo ricordo, e preferisco avere meno entità possibili accessibili in ogni blocco di software.

1. non viene mai spiegato a cosa serve e qual è la fallacia. Poiché si tratta di un tipo speciale di dati, è possibile impostare l'accesso come si desidera. L'esempio è chiaramente una scelta infelice.

2. È ovviamente un pensiero sbagliato negare al programmatore l'accesso ai suoi dati nel suo programma con il pretesto che farà un errore lì, poiché dovrà creare ogni sorta di intricati workaround per permettere l'accesso al programmatore e creare codice instabile con un sacco di possibili bug sulla strada. È come proibire al guidatore di toccare il volante, e poi inventare dei workaround-interfacce come lui può poi guidare l'auto al posto del volante.

 
Andrei:

2. Vietare ad un programmatore l'accesso ai propri dati nel proprio programma con il pretesto che presumibilmente farebbe casino lì - è ovviamente un pensiero errato, perché poi si deve creare ogni sorta di sofisticati workaround per dare l'accesso al programmatore e lungo la strada si crea codice instabile con un mucchio di possibili bug. È come proibire al guidatore di toccare il volante, e poi inventare dei workaround-interfacce come può poi guidare l'auto al posto del volante.

No. Ovunque nel codice - solo ciò che è necessario in quel posto dovrebbe essere disponibile - tutto il resto dovrebbe essere tagliato fuori, se possibile.

Nella tua situazione con il conducente - significa che è ragionevole vietare al conducente di toccare il volante mentre l'auto è parcheggiata. Quindi non cerca di girare una ruota mentre l'auto è parcheggiata - infatti, in quel momento, i sensori di allineamento delle ruote, per esempio, possono essere collegati alle ruote, e afferrare la ruota da parte del conducente porterà a errori nell'impostazione di quegli angoli.

L'idea è che in qualsiasi momento, solo la funzionalità di cui il programma ha bisogno in quel momento è disponibile per lui, e tutto il resto sarebbe chiuso. Sono stato a lungo convinto che questo è il modo per fare meno errori.

 
George Merts:

No. Proprio ovunque nel codice - solo ciò che è necessario in quel posto dovrebbe essere disponibile - tutto il resto dovrebbe essere tagliato, se possibile.

L'idea è che in ogni momento solo quelle funzioni sono disponibili al programma che sono necessarie in quel momento e tutto il resto deve essere bloccato. Ho imparato molto tempo fa che questo è il modo per fare meno errori.

Preoccuparsi costantemente di cosa proibire e cosa permettere è ovviamente un requisito molto illogico, a meno che ovviamente il programmatore non sia ubriaco quando scrive codice e non si controlli che potrebbe scrivere un mucchio di codice che non capisce. Penso che non aiuterà un programmatore alcolizzato e ubriaco ad evitare errori nel codice, e le persone sobrie non ne hanno bisogno in primo luogo.

 
Andrei:

Preoccuparsi costantemente di cosa proibire e cosa permettere è ovviamente un requisito molto illogico, a meno che ovviamente il programmatore non si sieda a scrivere codice mentre è ubriaco e non abbia il controllo su se stesso che può scrivere un sacco di codice che non capisce. Penso che non aiuterà un programmatore alcolizzato e ubriaco ad evitare errori nel codice, e le persone sobrie non ne hanno bisogno in primo luogo.

Questo è un requisito molto logico a cui molte persone arrivano.

Non ne hai bisogno - beh... non usare OOP.