Domande su OOP (programmazione orientata agli oggetti) - pagina 2

 
VOLDEMAR:

Come sempre, volevo imparare, ma ci sono sempre quelli che non hanno più niente da dire se non essere intelligenti...

Ho scritto un semplice esempio per smontarlo, non so come scrivere in modo più competente con OOP ... È solo un esempio, se sai come scrivere un codice simile correttamente e OOP allora per favore scrivi, così che io e altri possano imparare...

OOP inizia con la ricerca di un oggetto. Se non c'è un oggetto, non c'è OOP.

Di solito, un oggetto è alcune risorse, dati.

Devi solo scrivere e guardare come scrivono gli altri. Poi lo capirete da soli. Puoi anche leggere libri di testo. Ce ne sono molti su Internet.

 
Zhunko:

OOP inizia con la ricerca di un oggetto. Se non c'è un oggetto, non c'è OOP.

Di solito, un oggetto è alcune risorse, dati.

Devi solo scrivere e guardare come scrivono gli altri. Poi lo capirete da soli. Puoi anche leggere libri di testo. Ce ne sono molti su Internet.


Consiglia un paio di libri di testo per favore... Il più facile e più utile secondo voi...
 
VOLDEMAR:

Consiglia un paio di tutorial per favore ... Il più facile e più utile secondo voi...

Grady Buch. "Analisi e progettazione orientata agli oggetti. Con esempi di applicazioni C++".

Ire Paul (talvolta scritto Ira Paul) "Programmazione orientata agli oggetti in C++".

 

1) Non legato all'OOP, ma il gestore degli errori delle operazioni commerciali(OrderSend(), OrderDelete(), OrderModify() ) dovrebbe essere aggiunto...

Per renderlo rilevante per l'OOP - renderlo un metodo di classe virtuale (per sovrascriverlo in classi discendenti, aggiungendo l'elaborazione di altri codici).

2) Tutti i metodi di classe che nelle classi discendenti possono funzionare diversamente da ora - rendetelivirtuali.

Il primo candidato è openorders().

Lo svantaggio è che nei metodi virtuali non si può cambiare il numero e il tipo di parametri.

Il lato positivo è che i "vecchi" Buy, Sel, BuyStop ecc. saranno in grado di chiamare il "nuovo" (modificato nella classe figlio) openorders()

3) Facciamo subito dei nomi più carini. OpenOrders invece di openorders, per esempio.

4) Se la terminologia è chiamare qualcosa, allora si usa una terminologia simile.

Se vendere = VENDERE, allora si chiama Vendere o VENDERE (cioè SellStop invece di SelStop)

5) È necessario rimuovere tutte le costanti (500, ecc.) dalla classe.

Che siano prese da variabili o impostate come parametri di metodi.

Ora vi ricordate circa 500 incorporati in openorders(), ma più tardi ve ne dimenticherete o scriverete molti gufi usando queste classi e sarà difficile cambiare qualcosa.

La cosa più difficile da correggere sono gli errori architettonici.

Ed è lo scheletro che stai creando ora (se non è solo un esercizio).

6) Non mettere tutto in una classe.

Fate una classe clOrder e infilateci SetSL, CloseOrder, GetSL, GetProfit, SetTP, GetTP , ecc.

E nella classe clTrade , aggiungere un array/elenco di ordini, un simbolo e le proprietà del simbolo(TICKETSIZE, POINT, TICKETVALUE, MINLOT, MAXLOT, STOPSTEP, LOTSTEP, LOTSIZE, ecc.)

Se allegate Ask e Bid (come proprietà di un simbolo), non dimenticate di aggiornarle in OnTick().

Per RefreshRates(), fare un binding in modo che dopo l'aggiornamento delle variabili МТТ vengano chiamate le proprietà Ask e Bid (ho anche controllato lo stato degli ordini, chi ha aperto e chi ha chiuso. Quelli chiusi vengono rimossi dalla lista degli ordini).

È possibile aggiungere il calendario (prima di tutto, fare una classe) e il trailing stop (anche questo fare una classe separata).

PS: ho fatto tutto nel fine settimana (ho fatto la libreria per i commerci), ma questa volta ho deciso senza classi (solo strutture, array di strutture e funzioni che lavorano con tutto ciò).

C'è anche un programma per ogni giorno (dato che Alps on gold ha una pausa ogni giorno dalle 0:00 alle 1:00). Negli ultimi 2 minuti di trading, il controllore del programma chiude tutte le transazioni e cancella tutti gli ordini.

E nell'ultima ora di trading - chiude i trade perdenti, cancella gli ordini e trilla quelli redditizi. Ho anche fatto un trailing stop. Un tipo, ma si adatta a diversi simboli a causa dei diversi parametri.

Lo schema è il seguente: simboli (con i propri campi), ordini (con i propri campi), orari (con i propri campi) e un Expert Advisor con i propri campi (magik, ecc.) che si riferisce a un simbolo e ha una lista di ordini e una lista di orari.

La cima della gerarchia è la lista dei consiglieri (la combinazione simbolo+magia deve essere unica).

 
VOLDEMAR:

Consigliare alcuni tutorial per favore ... Il più semplice e utile secondo voi...

Esempi scritti usando OOP appaiono ora in CodeBase. Da VOLDEMAR, per esempio ))))

In realtà il tuo https://www.mql5.com/ru/code/11159 è ciò che mi ha ispirato a riscrivere la mia libreria commerciale per le strutture.

Ho deciso di aspettare con le classi - non vedo il punto di usarle in MQL .

 
Non ho capito bene, è possibile usare la classe Trade standard ora?
O è standard solo in MQL5, ed è appena ripreso da lì nel nuovo MetaEditor?
 
EverAlex:

Esempi scritti usando OOP appaiono ora in CodeBase. Da VOLDEMAR, per esempio ))))

In realtà, il tuo https://www.mql5.com/ru/code/11159 è ciò che mi ha ispirato a riscrivere la mia libreria commerciale per le strutture.

Ho deciso di aspettare con le classi - non vedo il punto di usarle in MQL finora.


Sì, l'ho scritto, ma a parte il trasferimento di funzioni in una classe, non ho ancora capito altro,
 
VOLDEMAR:

Sì, l'ho scritto, ma a parte il trasferimento di funzioni in una classe non ho ancora capito altro,

3(+1) Principi OOP:

1) Incapsulamento. Cioè la memorizzazione di variabili, pseudo variabili (chiamate "proprietà dell'oggetto" o semplicemente "proprietà") nell'oggetto stesso. Cioè, se una classe è dichiarata correttamente, i suoi dati non possono essere cambiati dall'esterno.

Solo usando funzioni della classe stessa (chiamate "metodi di classe" o semplicemente "metodi"). Necessario non solo per assegnare un valore a una variabile, ma per eseguire qualche azione in relazione al cambiamento di quei campi.

E questa è la principale (secondo me) utilità dell'introduzione dell'OOP in MQL, piuttosto che il porting delle funzioni (le funzioni della mia libreria commerciale ricevono l'indice dell'EA come uno dei parametri e lavorano con l'EA selezionato, incluso il suo array di ordini).

Nessuno può entrare nei dati di una classe creata da voi (se non c'è codice sorgente) e poi lamentarsi che il vostro codice ha degli errori.

2) Eredità. Quando una classe antenata viene creata, eredita tutti i campi e i metodi della classe antenata (c'è un tipo privato per i campi e i metodi che non possono essere visti nelle classi antenate, ma lo omettiamo per ora).

E qui nella fase di progettazione dell'oggetto è necessario pensare chiaramente all'architettura - come la classe sarà usata, quali campi conterrà, come dovrebbero essere visibili nelle classi discendenti, ecc.

È usato in sistemi potenti e librerie di classi, per compiti che personalmente non vedo nei compiti commerciali. Ma forse qualcuno ne avrà bisogno. Potete creare classi discendenti con diversi trailing stop, per esempio.

Ecco perché - nessuna costante all'interno dei metodi, tutto deve essere impostato esternamente tramite metodi appropriati (di solito iniziano con .Set) o direttamente come parametri dei metodi. Questo è quello che intendo per i tuoi 500.

3) Polimorfismo. La cosa che ho scritto un paio di post sopra - quando un rimodellato in una funzione di classe discendente openorders() chiamerà liberamente le vecchie funzioni Buy().

Un esempio di polimorfismo è il calcolo dell'area di una figura geometrica per diverse forme.

Si calcola in un modo per un cerchio, in un altro modo per un quadrato. Ma in ogni caso - chiamando Figura.GetSquare() otterremo l'area di una forma particolare ereditata da una classe base (se non abbiamo dimenticato di dichiarare Square() ).

Anche in questo caso è necessaria una certa qualificazione per creare l'architettura della classe base. Per esempio, dimenticare di dichiarare Square() come virtuale renderà impossibile chiamare Square in modo generico (dovrete controllare il tipo di classe prima di ogni chiamata e chiamare la sua implementazione di Square).

Alcuni raccomandano di rendere virtuali tutti i metodi tranne i costruttori (io la penso allo stesso modo se non si vede l'orizzonte di ciò che questa classe può diventare quando la si crea). La cosa principale è che anche i distruttori devono essere virtuali.


Aggiornamento:

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

4) Astrazione (come richiesto dai compagni, anche se quando ho studiato OOP (negli anni '90) non era considerato un principio (per l'appunto - solo derivato dai primi tre), e nell'articolo (vedi link sotto) si scrive di esso, ma non è nel titolo dell'articolo, sono solo 3).

Nell'applicazione pratica è la creazione di una classe base "vuota" (dove i metodi sono dichiarati, ma non fanno nulla). In alcuni linguaggi, un metodo può essere contrassegnato come astratto, il che significa che in una classe discendente deve essere necessariamente sovrapposto (cioè viene aggiunto un metodo che fa qualcosa).

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

PS: potete leggere brevemente, senza entrare nel merito, qui


PPS: non voglio offendere nessuno, ma quando ho chiesto in Work di scrivere una libreria commerciale, solo 1 persona ha risposto che ce l'ha e la usa.

5 programmatori MQL (su Skype) hanno detto che non hanno idea di cosa dovrebbe esserci dentro e fanno copia-incolla delle funzioni richieste da uno dei loro gufi all'altro. Addirittura infilano RefreshRates() tra frammenti di codice che non cambiano nulla e non possono essere eseguiti più di qualche millisecondo. E il codice successivo non dipende dalla modifica di Ask e Bid e (forse) dai tipi di ordini.

Pertanto, per i programmatori MQL che non hanno lavorato con OOP in altri linguaggi di programmazione prima, l'OOP in MQL non sarà utile. Al massimo, nasconderà i dati dai cambiamenti esterni (il che non è neanche male).

 
EverAlex:

3) I 3 principi di OOP:

1) Incapsulamento. Cioè la memorizzazione di variabili, pseudo-variabili (chiamate "proprietà dell'oggetto" o semplicemente "proprietà") nell'oggetto stesso. Cioè, se una classe è dichiarata correttamente, i suoi dati non possono

2) Eredità. Quando una classe antenata viene creata, eredita tutti i campi e i metodi della classe antenata (c'è un tipo privato per campi e metodi che non può essere visto nelle classi antenate, ma lo omettiamo qui per ora).

3) Polimorfismo. Quello che ho scritto qualche post sopra - quando rimodellato in una classe discendente la funzione openorders() chiamerà tranquillamente le vecchie funzioni Buy(), ecc.

Un esempio di polimorfismo è il calcolo dell'area di una figura geometrica per varie forme.

Si calcola in un modo per un cerchio e in un altro modo per un quadrato. Ma in ogni caso, chiamando Figura.GetSquare() otterremo l'area di una particolare forma ereditata dalla classe base (a meno che non abbiamo dimenticato di dichiarare Square() ).

Dov'è il quarto?! Dov'è l'estratto! Indegnamente dimenticato :-(
 
Zhunko:
Dov'è il quarto?! Dov'è l'estratto! Indegnamente dimenticato :-(


Aggiungere.
Motivazione: