Potresti confondere classi, implementare comportamenti e istanze di classe , che possono contenere dati che distinguono un'istanza di una classe da un'altra.
Per la semplice situazione che descrivi, puoi creare una classe di categorie di base, che definisce i comportamenti di
- Avere un nome.
- Avere un id.
- Contenente un elenco (eventualmente vuoto) di elementi.
- Avere un elenco (eventualmente vuoto) di sottocategorie.
* Avere un nome "significa consentire che il nome sia letto e (facoltativamente) aggiornato. Lo stesso vale per gli elenchi.
Puoi potresti dargli anche un parent
id, ma questo non è necessario se inizi sempre dalla tua categoria di alto livello e non lavori, dipende da come attraversi la struttura. Per il momento, supponiamo che tu non ne abbia bisogno ...
Ad ogni modo, dopo aver creato questa classe, puoi creare successive istanze della classe, assegnando a ciascuna un nome, aggiungendo elementi e sottocategorie ecc.
Riesci a vedere che il comportamento di ogni istanza è coerente? Ogni istanza può avere un id
unico, ma l'azione di recuperare o aggiornare quella proprietà è la stessa per tutte le istanze.
Ora, se fai hai bisogno che le tue sottocategorie sappiano qual è il loro genitore, a questo punto considererei due classi diverse: una per le categorie di primo livello e un'altra per le sottocategorie. Pur avendo una classe e lasciando vuota la proprietà "genitore" nelle categorie di alto livello, la possibilità di errore si apre, ma si caricano anche le categorie di alto livello con i campi e i metodi in eccedenza che dovranno (o dovrebbero ) mai usare. Considera queste dichiarazioni contrastanti:
- Una categoria di primo livello non dovrebbe mai avere un genitore
- Una sottocategoria ha sempre un genitore
- Rendi una categoria una sottocategoria dandole un genitore
- Puoi indicare una categoria di primo livello perché non ha un genitore
Come eviti di dare casualmente una categoria di primo livello a un genitore? O rimuovere accidentalmente il genitore di una sottocategoria? Come rilevi questi errori, dopo che sono accaduti? L'unico modo per distinguere un livello superiore da una sottocategoria è la cosa che hai appena rotto!
D'altra parte, se hai classi separate per le categorie principali e le sottocategorie, allora puoi avere una classe di categoria di primo livello che semplicemente non ha un campo parent
o qualsiasi metodo relativo ai genitori, e una classe di sottocategoria che deve avere. Non provi mai accidentalmente a scoprire il genitore di una categoria di alto livello perché è qualcosa che solo le sotto-categorie possono avere.
Ovviamente, ora hai il problema del comportamento condiviso delle categorie principali e secondarie. Una volta la risposta è avere una classe category
più semplice da cui ereditano entrambi. Un altro è quello di definire una category
interfaccia e avere entrambe le classi di sottocategoria e sottocategoria implementarlo . Ad ogni modo, il codice che si preoccupa solo del comportamento di categoria generale può considerarli entrambi uguali.
Per rendere la gestione di category
la responsabilità di items
, penso che l'hai capovolta. Le categorie devono sapere qualcosa su items
, perché le contengono. Nella maggior parte delle situazioni, items
non ha bisogno di sapere nulla su categories
. Le categorie sono raramente proprietà essenziali degli oggetti; rendere consapevole l'implementazione dell'articolo in base alle categorie significa che se si modifica la progettazione della categoria, è necessario modificare anche la progettazione dell'articolo. Questo è chiamato accoppiamento stretto , che è generalmente considerato una cattiva pratica. All'inizio può sembrare contro-intuitivo, ma in genere è meglio progettare i diversi componenti di un sistema per conoscere il minimo possibile di altri componenti, esponendo il meno possibile i propri dettagli interni. Questo è noto come separazione dei dubbi (o "accoppiamento lento").
Come nota finale, considera se sono necessari i campi id
. Se queste categorie sono memorizzate in un database, è potrebbe essere necessario se questa parte del codice potrebbe anche cambiare i nomi delle categorie. Ma ricorda che la sottocategoria "Bar" di "Bike Parts" può essere identificata in modo univoco come "/ Bike Parts / Bars" e quindi completamente distinta da "/ Venues / Bars". Anche se l'ID numerico è presente nel DB, potresti non volerlo nel tuo codice web - o non ovunque, comunque. Considera se desideri che i siti esterni rimandino a http://yoursite.com/Venues/Bars
o http://yoursite.com/cat3/cat21
.
Se non hai ancora pensato fino alla persistenza - o se la struttura della categoria non verrebbe archiviata in un database - proverei prima a implementarla senza gli id.