2009-02-22 21 views
10

Sono spesso in una situazione in cui ho un concetto rappresentato da un'interfaccia o una classe e quindi ho una serie di sottoclassi/sottointerfacce che la estendono.Best practice per denominare sottoclassi

Per esempio: Un generico "DoiGraphNode" A "DoiGraphNode" che rappresenta una risorsa A "DoiGraphNode" che rappresenta una risorsa Java A "DoiGraphNode" con un percorso associato, ecc, ecc

I puoi pensare a tre convenzioni di denominazione e apprezzare i commenti su come scegliere.


Opzione 1: iniziare sempre con il nome del concetto.

Così: DoiGraphNode, DoiGraphNodeResource, DoiGraphNodeJavaResource, DoiGraphNodeWithPath, ecc

Pro: E 'molto chiaro che cosa ho a che fare con, è facile vedere tutte le opzioni che ho

Contro: Non molto naturale? Tutto sembra uguale?


Opzione 2: inserire gli oggetti speciali all'inizio.

Così: DoiGraphNode, ResourceDoiGraphNode, JavaResourceDoiGraphNode, PathBaseDoiGraphNode, ecc, ecc

Pro: E 'molto chiaro quando lo vedo nel codice

Con: Trovare potrebbe essere difficile, soprattutto se non ricordo il nome, la mancanza di coerenza visiva


Opzione 3: Mettere la roba speciale e rimuovere una parte del testo ridondante

Così: DoiGraphNode, ResourceNode, JavaResourceNode, GraphNodeWithPath

Pro: Non è così molto da scrivere e leggere Con: Sembra che cr * p, molto incoerente, può entrare in conflitto con altri nomi

risposta

4

Nome loro per quello che sono.

Se nominarli è difficile o ambiguo, è spesso un segno che la Classe sta facendo troppo (principio di responsabilità singola).

Per evitare conflitti di denominazione, scegliere i propri spazi dei nomi in modo appropriato.

Personalmente, mi piacerebbe utilizzare 3

+1

Avrei anche scelto la terza opzione. Nei primi due c'è il pericolo di finire in un "labirinto di nomi lunghi e tortuosi, tutti leggermente diversi" in cui si fa fatica a leggerli e persino a ricordare quale nome corrisponde a quale concetto. – starblue

5

Utilizzare quello che vuoi, è una cosa soggettiva. L'importante è chiarire cosa rappresenta ogni classe e i nomi dovrebbero essere tali che le relazioni di ereditarietà abbiano un senso. Non penso davvero che sia così importante codificare le relazioni nei nomi, però; questo è a cosa serve la documentazione (e se i tuoi nomi sono appropriati per gli oggetti, le persone dovrebbero essere in grado di fare buone ipotesi su ciò che eredita da cosa).

Per quel che vale, io di solito uso l'opzione 3, e dalla mia esperienza guardando opzione codice di altre persone 2 è probabilmente più diffuso di quanto l'opzione 1.

0

Opzione tre in più la conseguenza logica del concetto di ereditarietà. Poiché stai specializzando l'interfaccia o la classe, il nome dovrebbe mostrare che non sta più utilizzando l'implementazione di base (se ne esiste una).

Ci sono una moltitudine di strumenti per vedere da cosa viene ereditata una classe, quindi un nome conciso che indica la funzione reale della classe andrà più lontano del tentativo di inserire nel nome troppe informazioni di tipo.

2

È possibile trovare alcune indicazioni in un documento di standard di codifica, ad esempio il documento IDesign per C# here.

Personalmente, preferisco l'opzione 2. Questo è in genere il modo in cui .NET Framework nomina gli oggetti. Ad esempio, guarda le classi di attributi. Finiscono tutti in Attribute (TestMethodAttribute). Lo stesso vale per EventHandlers: OnClickEventHandler è un nome consigliato per un gestore di eventi che gestisce l'evento Click.

Di solito cerco di seguirlo nel progettare il mio codice e le mie interfacce. Così un IUnitWriter produce un StringUnitWriter e un DataTableUnitWriter. In questo modo so sempre qual è la loro classe base e si legge più naturalmente. Il codice di autocertificazione è l'obiettivo finale per tutti gli sviluppatori agili, quindi sembra che funzioni bene per me!

1

Io di solito nome simile all'opzione 1, soprattutto quando le classi saranno utilizzate in modo polimorfico. Il mio ragionamento è che la parte più importante delle informazioni è elencata per prima. (I.e il fatto che la sottoclasse è fondamentalmente ciò che è l'antenato, con (in genere) le estensioni "aggiunte"). Mi piace questa opzione anche perché quando si ordinano gli elenchi dei nomi delle classi, le classi correlate verranno elencate insieme. I.e. Di solito, l'unità di traduzione (nome file) è la stessa di , quindi i file di classe correlati verranno elencati insieme. Allo stesso modo questo è utile con la ricerca incrementale.

Anche se prima tendevo a utilizzare l'opzione 2 nella mia carriera di programmatore, ora lo evito perché, come dici tu, è "incoerente" e non mi sembra molto ortogonale.

Io uso spesso l'opzione 3 quando la sottoclasse fornisce un'estensione o una specifica sostanziale o se i nomi sarebbero piuttosto lunghi. Per esempio, il mio file classi nome di sistema sono derivati ​​da String ma estendere notevolmente la classe String e hanno un significativamente differente uso/significato:

Directory_entry_name derivato da String aggiunge funzionalità estese. Nome file derivato da Directory_entry_name ha funzioni piuttosto specializzate. Directory_name derivato da Directory_entry_name ha anche funzioni piuttosto specializzate.

Insieme all'opzione 1, di solito utilizzo un nome non qualificato per una classe di interfaccia. Ad esempio, potrei avere una catena di classe interence:

  • Testo (un'interfaccia)
  • Text_abstract (abstract (di base) di classe generalizzazione)
  • Text_ASCII (classe concreta specifica per codifica ASCII)
  • Text_unicode (classe concreta specifica per codifica unicode)

Mi piace piuttosto che l'interfaccia e la classe base astratta compaiano automaticamente per primi nell'elenco ordinato.