Scrivere nomi, verbi, aggettivi è un ottimo approccio, ma preferisco pensare al design di classe come a porre la domanda quali dati dovrebbero essere nascosti ?
Immagina di avere un Query
oggetto e un Database
oggetto:
L' Query
oggetto ti aiuterà a creare e memorizzare una query - store, è la chiave qui, in quanto una funzione potrebbe aiutarti a crearne uno altrettanto facilmente. Forse si poteva stare: Query().select('Country').from_table('User').where('Country == "Brazil"')
. Non importa esattamente la sintassi: quello è il tuo lavoro! - la chiave è che l'oggetto ti aiuta a nascondere qualcosa , in questo caso i dati necessari per archiviare e generare una query. Il potere dell'oggetto deriva dalla sintassi del suo utilizzo (in questo caso un concatenamento intelligente) e non è necessario sapere cosa memorizza per farlo funzionare. Se eseguito correttamente, l' Query
oggetto potrebbe generare query per più di un database. Memorizzerebbe internamente un formato specifico ma potrebbe facilmente convertirsi in altri formati durante l'output (Postgres, MySQL, MongoDB).
Ora pensiamo attraverso l' Database
oggetto. Cosa nasconde e memorizza? Beh, chiaramente non può memorizzare l'intero contenuto del database, poiché è per questo che abbiamo un database! Quindi qual è il punto? L'obiettivo è nascondere il funzionamento del database alle persone che utilizzano l' Database
oggetto. Le buone classi semplificheranno il ragionamento durante la manipolazione dello stato interno. Per questo Database
oggetto è possibile nascondere il funzionamento delle chiamate in rete o eseguire query o aggiornamenti in batch o fornire un livello di memorizzazione nella cache.
Il problema è che questo Database
oggetto è ENORME. Rappresenta come accedere a un database, quindi sotto le coperte potrebbe fare qualsiasi cosa. Chiaramente la rete, la memorizzazione nella cache e il batch sono abbastanza difficili da gestire a seconda del sistema, quindi nasconderli sarebbe molto utile. Ma, come noteranno molte persone, un database è follemente complesso e più lontano dalle chiamate di DB non elaborate si ottiene, più è difficile ottimizzare le prestazioni e capire come funzionano le cose.
Questo è il compromesso fondamentale di OOP. Se scegli l'astrazione giusta, la codifica diventa più semplice (String, Array, Dictionary), se scegli un'astrazione troppo grande (Database, EmailManager, NetworkingManager), potrebbe diventare troppo complesso per capire davvero come funziona o cosa aspettarsi. L'obiettivo è nascondere la complessità , ma è necessaria una certa complessità. Una buona regola empirica è iniziare evitando Manager
oggetti e creare invece classi simili structs
: tutto ciò che fanno è conservare i dati, con alcuni metodi di supporto per creare / manipolare i dati per semplificarti la vita. Ad esempio, nel caso di EmailManager
inizio con una funzione chiamata sendEmail
che accetta un Email
oggetto. Questo è un semplice punto di partenza e il codice è molto facile da capire.
Per quanto riguarda il tuo esempio, pensa a quali dati devono essere uniti per calcolare ciò che stai cercando. Se volessi sapere fino a che punto camminava un animale, ad esempio, potresti avere AnimalStep
e AnimalTrip
(collezione di AnimalSteps) classi. Ora che ogni viaggio ha tutti i dati Step, allora dovrebbe essere in grado di capire cose al riguardo, forse AnimalTrip.calculateDistance()
ha senso.