Perché dovremmo preferibilmente utilizzare raccolte di prima classe?


15

Secondo la regola numero 4 di Object Calisthenics di Jeff Bay (RTF) in The ThoughtWorks Anthology, si consiglia di " Utilizzare raccolte di prima classe ".

Regola 4: raccolte di prima classe

L'applicazione di questa regola è semplice: qualsiasi classe che contiene una raccolta non deve contenere altre variabili membro. Ogni collezione viene avvolta nella sua classe, quindi ora i comportamenti relativi alla collezione hanno una casa. È possibile che i filtri diventino parte di questa nuova classe. Inoltre, la tua nuova classe può gestire attività come l'unione di due gruppi insieme o l'applicazione di una regola a ciascun elemento del gruppo.

Ciò che ho potuto capire da questo è che dovremmo usare una classe separata che avvolge la raccolta e con metodi per aggiungere, eliminare i dati di modifica di quella raccolta.

e ne abbiamo bisogno in modo da essere sicuri di quale tipo di dati va nella raccolta e di ciò che viene fuori.

Nel caso in cui utilizziamo la raccolta generica (nelle lingue in cui è applicabile), dobbiamo seguire questa regola?

Se mi manca un significato importante, chiarire.


1
Amogh Talpallikar Ho cambiato la regola 8 in regola 4, in quanto la regola 8 è in realtà "Nessuna classe con più di due variabili di istanza".
yannis,

Sembra dire la Regola 8 nel sommario e quindi chiamarla Regola 4 nel corpo.
Inutile


6
Sono solo io o questa regola non è implementabile come scritto? Voglio dire, hai una lezione con una raccolta, quindi prendi tutto il resto. Ora la tua classe è una raccolta. Quindi, se hai un'altra classe, con quella classe, ha una raccolta e ... schiuma, risciacqua, ripeti.
mjfgates,

@mjfgates: hmm ... Ottimo punto! qualcosa a cui pensare davvero!
Amogh Talpallikar,

Risposte:


12

La sicurezza dei tipi è una ragione molto piccola per usare raccolte di prima classe. Dal tuo link:

Regola 4: raccolte di prima classe L'applicazione di questa regola è semplice: qualsiasi classe che contiene una raccolta non deve contenere altre variabili membro. Ogni collezione viene avvolta nella sua classe, quindi ora i comportamenti relativi alla collezione hanno una casa. È possibile che i filtri diventino parte di questa nuova classe. Inoltre, la tua nuova classe può gestire attività come l'unione di due gruppi insieme o l'applicazione di una regola a ciascun elemento del gruppo.

L'idea qui è se ti trovi a cercare, filtrare, convalidare o altro oltre a aggiungere / rimuovere / iterare la semantica su una raccolta, il codice ti chiede di inserirlo nella sua classe. Se è necessario aggiornare solo un valore (dopo una ricerca), probabilmente va nella classe di raccolta.

Il ragionamento per questo è piuttosto semplice, le collezioni tendono a passare in giro. Ben presto, 4 classi diverse hanno il loro SearchByID()metodo. Oppure ottieni valori di ritorno come Map<Integer, String>con il contesto di ciò che è memorizzato in quella mappa rimosso. Una raccolta di prima classe è una soluzione semplice che costa un singolo file di origine. In pratica, una volta che sono presenti (sono anche molto facili scrivere test unitari), qualsiasi modifica relativa alla raccolta è facile da gestire, come quando è SearchByIDnecessario prendere un GUID anziché un int.


8

... usa una classe separata che avvolge la raccolta e con metodi per aggiungere, eliminare i dati di modifica di quella raccolta

Ciò non significa solo garantire il tipo di oggetti archiviati nelle raccolte, ma garantisce anche eventuali invarianti delle raccolte.

Gli alberi (rosso-nero, AVL ecc.) Sono sensibili all'ordinamento e il loro comportamento dipende dal riequilibrio, se del caso. Le prestazioni della tabella hash dipenderanno anche dal re-hashing appropriato. Vuoi ricordare di controllare il fattore di carico ogni volta che lo inserisci in una mappa hash?

FWIW, il testo è abbastanza chiaro su questo (e modificherò il tutto nella tua domanda, quindi nessun altro ha bisogno di scaricare quell'RTF):

Ogni collezione viene avvolta nella sua classe, quindi ora i comportamenti relativi alla collezione hanno una casa

Niente a che fare con i tipi (o quindi generici), tutto a che fare con l'associazione del comportamento della raccolta ai suoi dati.


1

La semplice risposta è "No" se si utilizza un linguaggio che supporta Generics. Perché non c'è bisogno di controllare il tipo poiché la funzione di linguaggio in sé fa un buon lavoro in questo (dalla mia esperienza generica Java).

Ma se hai qualche situazione in cui desideri personalizzare la struttura di dati fornita dalla lingua, puoi creare una classe wrapper attorno alla struttura di dati originale ed esporre le tue API e continuare a utilizzare l'implementazione sottostante della struttura di dati originale.


Sto anche pensando in modo simile. ma dovrebbe esserci qualcosa, gli esempi che ho visto per questo sono stati in Java e C # ed entrambi supportano raccolte generiche.
Amogh Talpallikar,

@AmoghTalpallikar: il mio punto era di renderlo semplice. A meno che non abbia bisogno di ignorare alcun comportamento specifico della struttura dei dati, non personalizzerò.
java_mouse,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.