Le classi nidificate sono sottovalutate?


9

Non sto cercando di dire che conosco qualcosa che gli altri non sanno, ma ho risolto sempre più progetti con l'uso di classi nidificate, quindi sono curioso di avere un'idea dell'accettabilità di usare questo apparentemente usato raramente meccanismo di progettazione.

Questo mi porta alla domanda: sto percorrendo una strada intrinsecamente sbagliata per ragioni che scoprirò quando torneranno a mordermi, o le classi nidificate forse sono qualcosa che sono sottovalutate?

Ecco due esempi per cui li ho appena usati: https://gist.github.com/3975581 - il primo mi ha aiutato a tenere insieme le cose gerarchiche strettamente legate, il secondo mi ha permesso di dare accesso ai membri protetti ai lavoratori ...


Voglio solo dire grazie per le risposte / approfondimenti - Non sono sicuro di come scegliere una risposta, quindi la lascerò mentre rimugino sui consigli che ho ricevuto e rivisitare ...
Aaron Anodide,

Risposte:


6

Non lo definirei un "meccanismo di progettazione usato raramente" - almeno, non universalmente: sebbene ci siano negozi in cui alcuni partecipanti potrebbero disapprovare l'uso di classi nidificate, questa non è affatto una caratteristica oscura.

Sebbene l'esistenza di classi con visibilità sull'assemblaggio e l'introduzione di lambdas abbia significativamente ridotto la necessità di classi nidificate * , rimangono una valida scelta progettuale. Sebbene vi sia una certa sovrapposizione con le classi interne all'interno di uno spazio dei nomi, la funzionalità delle classi nidificate è unica nel consentire di nascondere una classe interamente all'interno di un'altra classe.


* L'uso di una funzione simile in Java è molto più elevato, perché altre alternative disponibili in C # non sono presenti in Java.


Quindi è bello nascondere una classe interamente in un'altra classe secondo l'essenza del design OOP?
Maxood,

1
@Maxood È bello nascondere una lezione se puoi nasconderla. L'utente della tua API dovrebbe sapere il meno possibile sul modo in cui la tua API è implementata.
dasblinkenlight,

3

Considera per un momento che stai scrivendo una classe all'interno di un'altra classe, che non verrà mai utilizzata in nessun altro posto del tuo programma. Perché se lo stessi usando altrove, lo trasformeresti in una normale classe pubblica, proprio come tutti gli altri.

Quindi la cosa che dovrebbe rendere grande OOP (riusabilità) è assente qui. Inoltre, cosa potresti ottenere con una classe nidificata che non potresti ottenere con metodi ordinari e membri privati ​​all'interno della classe genitore?

Per un utile modello software che utilizza classi nidificate, guarda qui .


10
Non ho mai comprato la cosa della riusabilità, almeno non come è solito. (1) Chiamare in codice / classi esistenti (di cui sembri parlare e che di solito vedo come definizione di riutilizzo) non ha assolutamente nulla a che fare con OOP, è solo una modularità di base. (2) Il polimorfismo dei sottotipi, che è una delle caratteristiche distintive di OOP, consente il riutilizzo del codice client rendendo irrilevante l'implementazione specifica , ovvero funziona esattamente allo stesso modo indipendentemente dal fatto che la classe concreta sia accessibile o meno. IOW è il riutilizzo che compro, ma funziona anche con le classi nidificate.

1
Direi che c'è anche l'isolamento dello spazio dei nomi dato dalla classe genitore - quindi se lo desideri, entrambe le classi A e B potrebbero avere la classe nidificata "Params" e l'accesso ai membri non pubblici della classe contenitrice. Non sono entrambi motivi per avere classi interne che sono usate al di fuori della classe?
Aaron Anodide,

@AaronAnodide Questa dovrebbe essere una risposta su un buon modo per usare le classi nidificate. È esattamente come / perché li uso, aiuta a organizzare il codice.
Izkata,

2

am I going down an inherintly bad path

Penso che nel tuo secondo esempio (le sottoclassi dei lavoratori) lo sia sicuramente. Ogni sottoclasse è stata mappata su uno stato specifico nella superclasse. Quindi ora ogni volta che vuoi aggiungere uno stato alla superclasse dovrai fare una modifica in tre posizioni (aggiungi lo stato alla superclasse, aggiungi una nuova sottoclasse e cambia il costruttore della classe derivata per aggiungere la sottoclasse all'elenco ).

L'uso di classi nidificate per accedere a membri privati ​​sembra essere un uso valido (non l'ho mai fatto personalmente) ma il tuo caso specifico non funziona qui.

Per quanto riguarda l'esempio della parte del corpo. Poiché tutte le classi nidificate sono pubbliche, in realtà non stai facendo molto tranne lo spazio dei nomi. Se queste classi aumentano per includere più funzionalità, potresti semplicemente scoprire che le classi nidificate ingombrano semplicemente le interfacce e stai setacciando il codice per trovare qualcosa di specifico. Noto anche che, poiché hai classi nidificate, sei costretto a infrangere le convenzioni di denominazione e nominare le tue classi con lettere minuscole (forse questa è stata una scelta). Ma questi argomenti sono più superficiali di qualsiasi altra cosa effettivamente sbagliata.

A meno che, ovviamente, non fosse necessario implementare un braccio disincarnato. Quindi creare un braccio nel modo seguente è confuso perché non c'è corpo / busto / lato. (Notare anche l'involucro confuso).

arm newArm = new Body.torso.side.arm("");

1

L'unico vantaggio che mi viene in mente delle classi nidificate è che possono essere rese private (o protette). Direi che in questo caso le classi nidificate possono aiutarti a incapsulare la funzionalità se una classe è destinata a essere utilizzata dalla classe esterna e da quella classe da sola.


1

Nella mia esperienza, classi nidificate

  • Sono tornato per perseguitarmi
  • Sono stato usato quando volevo tagliare gli angoli
  • Ha reso il test un incubo
  • Ha avuto un impatto negativo sulla separazione delle preoccupazioni e sulla progettazione generale

Ho dato una breve occhiata alla tua classe e subito penso che:

  • È doloroso guardarlo perché la classe è enorme
  • Non posso testare le "dita" senza creare praticamente tutto il corpo
  • Non posso avere più implementazioni del busto. Non sembra così ovvio in un contesto di "corpo umano", ma in uno scenario diverso questo diventerebbe ovvio.

Perché non separare la tua classe in più classi e dare loro spazi dei nomi separati. Per esempio

WindowsGame1.PhysicalModel.UpperBody
WindowsGame1.PhysicalModel.LowerBody
WindowsGame1.PhysicalModel.UpperBody.Arms
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.