Quando dovrei annidare un modulo all'interno di un altro?

2

Supponiamo che io stia lavorando su un'applicazione JavaScript e faccia ampio uso del modello del modulo con un file per modulo. Supponiamo ora di avere due cartelle / moduli: uno per il modulo A e un altro per il modulo B. Il modulo A utilizza il modulo B e B non è utilizzato da nessun altro modulo. Dovrei inserire B all'interno di A o dovrebbero essere uguali? Quali sono i vantaggi / svantaggi di ciascuna decisione?

Devo farlo ...

  • A
    • B (usato solo da A)

... o questo ...

  • A
  • B (usato solo da A)

Sto cercando una risposta che elenca i vantaggi / compromessi per ciascuna opzione.

Ecco un punto di partenza in base alla mia esperienza:

A contenente B

I vantaggi:

  • La decisione più intuitiva / comune
  • Assicura che la posizione di B sia immediatamente evidente (in realtà, non è così difficile in entrambi i casi) - non scavare attraverso molti moduli nella root del progetto

Compromessi:

  • Non incoraggia gli sviluppatori a pensare a B come a un modulo autonomo, spesso portando a un eccessivo accoppiamento
  • Quando apporti modifiche, è più semplice trascurare un modulo esistente che può essere riutilizzato con il minimo sforzo (perché è annidato all'interno di una sottocartella)

Con JavaScript moderno, penso che i compromessi superino i benefici, ma potrei mancare qualcosa. Spero di trovare qualche tipo di verità universale - forse anche una che possa essere applicata a concetti simili (come pacchetti, DLL, spazi dei nomi, ecc.)

    
posta Johntron 08.03.2016 - 20:26
fonte

2 risposte

1

In practice, I think the first option makes it much easier to tightly-couple A to B, so I prefer the second option to encourage modularity; however, this taken to an extreme means you end up with a project with a single level of modules (i.e. a single folder that contains all of your modules), and that sounds kind of crazy.

Provenendo da una prospettiva C #, ci sono due conseguenze della prima opzione:

  1. Supponendo che B sia una classe nidificata privata, può solo essere parlata da A (io uso "parlato" piuttosto che accedere perché è il nome che è nascosto, i riferimenti alle istanze di A possono essere passati in giro).
  2. B può accedere ai membri privati di A.

Come affermi, questi fattori rendono possibile una coppia di classi strettamente accoppiate. Le classi accoppiate tendono ad essere meno mantenibili, poiché i cambiamenti in una classe tendono a richiedere cambiamenti in un'altra classe. Tuttavia, con una classe nidificata, questa preoccupazione viene mitigata dal fatto che la superficie della classe annidata è incapsulata all'interno della classe genitore. Pertanto, le modifiche alla classe nidificata non hanno alcun impatto sulle altre classi.

Quindi, direi che una classe annidata è appropriata quando si tratta di classi accoppiate intenzionalmente. Ad esempio, il link offre l'esempio di una classe SortedMap contenente una classe TreeNode privata. Annidando TreeNode , la classe può progettare una classe di TreeNode altamente specializzata da utilizzare solo per SortedMap , senza preoccuparsi che altri utenti lo utilizzeranno.

    
risposta data 08.03.2016 - 20:48
fonte
1

La domanda è un po 'troppo generica per dare una risposta definitiva in entrambi i modi. Se stai cercando di farti giudicare da questo giudizio, dipende in gran parte da quanto tempo devi ottenere qualcosa che funzioni fuori dalla porta.

Quindi con un grande pizzico di sale, e basato su un'ipotetica situazione di A / B senza alcun ulteriore contesto:

Vantaggi dell'accoppiamento di B all'interno di A :

  • Nel mondo reale, le scadenze e le esigenze aziendali superano l'ideologia tecnica.
  • Il codice potrebbe essere più facile da scrivere.
  • Il codice potrebbe essere più veloce da scrivere.
  • La soluzione generale potrebbe presentare una complessità leggermente inferiore / indiretta.
  • Non ostacolerà la tua capacità di creare una soluzione funzionante e corretta.
  • In alcuni (rari) casi B potrebbe dover contenere funzionalità che non devono mai essere riutilizzate al di fuori di A .
  • Una scelta pragmatica quando devi solo portare qualcosa fuori dalla porta al più presto.

Svantaggi di accoppiamento B all'interno A :

  • Stai effettivamente trattando A e B come la stessa classe.
  • Non puoi isolare nessuno dei due per riutilizzarli da soli.
  • Non puoi testare l'unità in isolamento.
  • Rischi di perdere la separazione e finire con alcune responsabilità sovrapposte tra A e B .
  • I test dell'unità potrebbero richiedere più tempo per la scrittura.
  • Potresti aver bisogno di più test unitari per ottenere una copertura completa.
  • I tuoi test unitari potrebbero essere più complessi e necessitano di un maggior set-up.
  • Non sarai in grado di modificare B senza cambiare implicitamente A .
  • Ogni volta che cambi B devi pensare al test per A .
  • Se hai bisogno di riutilizzare A o B in isolamento, dovrai refactoring.
  • Il tuo futuro rischio di incorrere in "debiti tecnici" è più elevato in futuro quando i requisiti cambiano.

A meno che tu non stia parlando di due classi con centinaia di righe di codice e molta logica complessa (nel qual caso entrambe le classi dovrebbero essere ulteriormente suddivise), allora niente di tutto questo è davvero un grosso problema.

Se "inquinanti spazi dei nomi" è un problema, allora rimbocca B nel proprio sottocreato. Non so quale lingua stai usando, ma di solito puoi avere più domini nello stesso modulo / pacchetto / dll / ecc. Gli spazi dei nomi di solito non dovrebbero essere un fattore nella tua decisione.

Ricorda, per qualsiasi decisione tecnica o di progettazione:

  • Quando il tempo è fondamentale, la risposta a come si sceglie di strutturare A e B è completamente accademica; la tua priorità principale in questo scenario è sempre per ottenere qualcosa che funziona solo entro il tempo consentito.
  • Il buon design è irrilevante quando si raggiunge una scadenza con software incompleto o rotto. Lavorare (corretto) software è sempre preferibile, anche quando il suo design e la sua struttura sono fastidiosi. È sempre possibile refactoring software di lavoro, ma non è possibile refactoring software che è incompleta o rotto.
risposta data 09.03.2016 - 00:07
fonte

Leggi altre domande sui tag