Voglio illustrare la mia domanda per mezzo di un esempio (si spera) rappresentativo.
Diciamo che ho una situazione in cui sto sviluppando una libreria di classi in C # da utilizzare in alcune simulazioni. Voglio definire i pianeti (Terra, Marte, Saturno, ecc.) E ognuno di loro ha alcune proprietà e metodi comuni nell'interfaccia (nome, firma, ecc.) Ma unici nell'implementazione per ciascuno. Cioè Earth.Mass non è uguale a Mars.Mass.
Finora niente di grave.
Voglio avere altre classi / metodi / algoritmi che accettano come argomento un pianeta e ne usano le proprietà e il metodo definiti:
double MyApparentWeight(Planet someplanet, double MassInKG)
double DistanceFromInKM(Planet someplanet, Planet originplanet)
I pianeti potrebbero essere utilizzati dappertutto da qualcuno che utilizza questa libreria. Tutti i "Terreni" dovrebbero essere identici e tutti i "Saturn" dovrebbero essere identici. Ovviamente i "Terreni" sono distinti da quelli di "Saturno".
Voglio anche che un utente della libreria sia in grado di creare facilmente un nuovo pianeta (ad esempio Vulcan, Endor, Tralfamadore, Persefone, Rupert, ecc.). Dovrebbe essere costretto a fornire le proprietà e i metodi di quelli esistenti e quindi essere utilizzabile con i metodi MyApparentWeight e DistanceFromInKM.
Quindi l'approccio di livello base è che esiste una classe Planet e quindi quelli specifici (Terra, Vulcan, ecc.) ereditano semplicemente da essa. In questo caso, tuttavia, l'utente deve creare un'istanza della Terra e portarla in giro o crearne una nuova ogni volta che è necessaria. Questo potrebbe essere inutilmente goffo (soprattutto alla luce degli utenti previsti) e probabilmente un colpo di performance dal momento che alcuni pianeti potrebbero avere passaggi di inizializzazione della data di lettura dai file, ecc.
L'idea successiva era la precedente ma con un paradigma singleton. Questo è fondamentalmente quello che ho fatto finora. Questo sembra dettare l'implementazione interna a tutti i nuovi Pianeti che vengono creati (e di nuovo alcuni di quelli che riguardano il potenziale livello di alcuni utenti).
Questo progetto è il modo in cui ho tagliato i miei denti C # /. NET. Il mio approccio iniziale ingenuo era di provare a fare classi statiche con interfacce o ereditarietà. Ovviamente ho imparato rapidamente la follia di quel percorso. Ad un livello elevato è il tipo di paradigma che avrei voluto comunque.
C'è qualche altro motivo di progettazione che mi manca che potrebbe coprire questo tipo di situazione?
Apprezzo i suggerimenti.
Aggiornamenti
Forse non ho chiarito che questo esempio di Planet
avrebbe dovuto essere solo strutturalmente illustrativo e non direttamente rappresentativo dei calcoli effettivi. Alcune persone sembravano un po 'coinvolte nell'implementazione di quali dati vengono rappresentati all'interno di essi e in altri aspetti periferici.
I suggerimenti dei singoli pianeti (come la Terra) pur essendo istanze della classe Planet
non hanno catturato i miei punti su implementazioni potenzialmente significative per i loro meccanismi interni che supportano i loro metodi e proprietà. Sono anche incerto sul modo in cui aiuta a non voler gestire il trascinamento di quelle istanze potenzialmente ovunque si desideri utilizzarle o dover creare nuove istanze.
L'estensione di Glenn del suggerimento di Stephen penso che in realtà funzioni meglio nel contesto di ciò di cui ho bisogno qui. Posso accoppiarlo con il suggerimento di rsbarro di avere proprietà statiche per i bambini costruiti in Planet
. (In realtà più come interface IPlanet
implementatori). Ciò fornisce l'accesso più semplice per gli utenti agli oggetti più comunemente usati e offre un leggero miglioramento delle prestazioni di non dover recuperare ogni volta dal dizionario per nome. Offre ancora la possibilità per gli utenti di aggiungere dinamicamente più tipi di Pianeti.
Non ho ancora il rappresentante per votare su tutte le risposte che ho citato sopra o lo farei.
Grazie a tutti per i vostri suggerimenti e feedback.