Qual è l'approccio migliore per denominare le classi?


92

Trovare nomi validi e precisi per le classi è notoriamente difficile. Fatto bene, rende il codice più auto-documentante e fornisce un vocabolario per ragionare sul codice a un livello più alto di astrazione.

Alle classi che implementano un particolare design pattern potrebbe essere assegnato un nome basato sul ben noto nome del pattern (es. FooFactory, FooFacade) e le classi che modellano direttamente concetti di dominio possono prendere i loro nomi dal dominio del problema, ma per quanto riguarda le altre classi? C'è qualcosa come il thesaurus di un programmatore a cui posso rivolgermi quando mi manca l'ispirazione e voglio evitare di usare nomi di classi generici (come FooHandler, FooProcessor, FooUtils e FooManager)?


6
questa è un'ottima domanda! Chiuderlo è IMHO ingiustificato, meglio sarebbe migrare il sito dei programmatori.
Timofey

1
Sono d'accordo, dovrebbe essere riaperto o spostato
ftl


Ho visto molte di queste eccellenti domande "chiuse da casperOne". Forse potrebbe servire come cancellista su Wikipedia?
Perlator

Risposte:


58

Citerò alcuni passaggi da Implementation Patterns di Kent Beck:

Nome superclasse semplice

"[...] I nomi dovrebbero essere brevi e incisivi. Tuttavia, per rendere i nomi precisi a volte sembra richiedere più parole. Una via d'uscita da questo dilemma è scegliere una metafora forte per il calcolo. Con una metafora in mente, anche singole parole portano con sé una ricca rete di associazioni, connessioni e implicazioni. Ad esempio, nel framework di disegno HotDraw, il mio primo nome per un oggetto in un disegno era DrawingObject . Ward Cunningham è arrivato con la metafora della tipografia: un disegno è come una pagina stampata e strutturata. Gli elementi grafici su una pagina sono figure, quindi la classe è diventata Figura . Nel contesto della metafora, Figure è contemporaneamente più breve, più ricca e più precisa di DrawingObject . "

Nome della sottoclasse qualificato

"I nomi delle sottoclassi hanno due compiti. Devono comunicare a che classe sono e in che modo sono diversi. [...] A differenza dei nomi alla radice delle gerarchie, i nomi delle sottoclassi non sono usati così spesso nelle conversazioni, quindi possono essere espressivi a costo di essere concisi. [...]

Assegna alle sottoclassi che fungono da radice delle gerarchie i loro nomi semplici. Ad esempio, HotDraw ha una classe Handle che presenta le operazioni di modifica della figura quando viene selezionata una figura. Si chiama, semplicemente, Maniglia nonostante si estenda Figura . C'è un'intera famiglia di maniglie e più appropriatamente hanno nomi come StretchyHandle e TransparencyHandle . Poiché Handle è la radice della propria gerarchia, merita un semplice nome di superclasse più che un nome di sottoclasse qualificato.

Un altro problema nella denominazione delle sottoclassi è rappresentato dalle gerarchie a più livelli. [...] Piuttosto che anteporre ciecamente i modificatori alla superclasse immediata, pensa al nome dal punto di vista del lettore. Di che classe ha bisogno per sapere che è questa classe? Usa quella superclasse come base per il nome della sottoclasse. "

Interfaccia

Due stili di denominazione delle interfacce dipendono da come pensi delle interfacce. Le interfacce come classi senza implementazioni dovrebbero essere denominate come se fossero classi ( Simple Superclass Name , Qualified Subclass Name ). Un problema con questo stile di denominazione è che i buoni nomi vengono utilizzati prima di arrivare a denominare le classi. Un'interfaccia chiamata File necessita di una classe di implementazione chiamata qualcosa come ActualFile , ConcreteFile o ( bleah !) FileImpl(sia un suffisso che un'abbreviazione). In generale, comunicare se si ha a che fare con un oggetto concreto o astratto è importante, se l'oggetto astratto è implementato come interfaccia o come superclasse è meno importante. Rimandare la distinzione tra interfacce e superclassi è> ben supportato da questo stile di denominazione, lasciandoti libero di cambiare idea in seguito se> diventa necessario.

A volte, nominare classi concrete è semplicemente più importante per la comunicazione che nascondere l'uso delle interfacce. In questo caso, anteporre ai nomi delle interfacce "I". Se l'interfaccia si chiama IFile , la classe può essere semplicemente chiamata File .

Per una discussione più dettagliata, acquista il libro! Ne vale la pena! :)


1
"A volte, nominare classi concrete è semplicemente più importante per la comunicazione che nascondere l'uso delle interfacce. In questo caso, anteporre ai nomi delle interfacce" I ". Se l'interfaccia si chiama IFile, la classe può essere semplicemente chiamata File." È così divertente, perché nel libro Clean Code di Robert C. Martin, ho scoperto che preferiremmo denominare le implementazioni come FileImpl, piuttosto che denominare l'interfaccia come IFile, perché non vogliamo che il cliente sappia che stiamo servendo loro un interfaccia. E nel libro ^ ci sono citazioni dal libro a cui ti riferisci :)
Cristian Ciobotea

38

Scegli sempre MyClassA, MyClassB: consente un buon ordinamento alfa ..

Sto scherzando!

Questa è una buona domanda, e qualcosa che ho sperimentato non molto tempo fa. Stavo riorganizzando la mia base di codice al lavoro e avevo problemi su dove mettere cosa e come chiamarlo ..

Il vero problema?

Avevo lezioni che facevano troppo. Se provi ad aderire al principio di responsabilità unica , renderà tutto molto più bello. Piuttosto che una classe monolitica PrintHandler , potresti suddividerla in PageHandler , PageFormatter (e così via) e quindi avere una classe principale Printer che riunisce tutto.

Nella mia riorganizzazione, mi ci è voluto del tempo, ma ho finito per raggruppare un sacco di codice duplicato, ho ottenuto la mia base di codice molto più logica e ho imparato molto quando si tratta di pensare prima di lanciare un metodo extra in una classe: D

Vorrei non tuttavia consigliamo di mettere le cose come i nomi dei pattern in nome della classe. L'interfaccia delle classi dovrebbe renderlo ovvio (come nascondere il costruttore per un singleton). Non c'è niente di sbagliato nel nome generico, se la classe ha uno scopo generico.

In bocca al lupo!


D'accordo con il non mettere nomi di pattern nel nome della classe. Cosa succede se il modello cambia in seguito quando cambia l'implementazione?
thegreendroid

2
Preferisco mettere un nome di pattern in un nome. Perché? Perché se devo guardare i dettagli di implementazione (come il costruttore privato) per scoprire che è un singleton, questo mi rallenta come lettore e, a seconda del mio livello di abilità, potrei non capire che in realtà è una parte di classe del modello generale. Singleton e costruttore privato è un esempio discutibile, ma per modelli più complicati (Visitor, Adapter ecc.) Sta diventando piuttosto complicato. Se lo schema cambia, è probabile che quelle classi non esisteranno più ...
dragan.stepanovic

28

L'eccellente discorso di Josh Bloch sulla buona progettazione delle API offre alcuni buoni consigli:

  • Le classi dovrebbero fare una cosa e farla bene.
  • Se una classe è difficile da nominare o da spiegare, probabilmente non sta seguendo il consiglio nel punto elenco precedente.
  • Il nome di una classe dovrebbe comunicare immediatamente qual è la classe.
  • I buoni nomi guidano i buoni progetti.

Se il tuo problema è come denominare classi interne esposte, forse dovresti consolidarle in una classe più grande.

Se il tuo problema è nominare una classe che sta facendo molte cose diverse, dovresti considerare di suddividerla in più classi.

Se questo è un buon consiglio per un'API pubblica, non può far male a nessun'altra classe.


1
collegamento video su youtube youtube.com/watch?v=aAb7hSCtvGw
Andrew Harry

12

Se sei bloccato con un nome, a volte solo dandogli qualsiasi nome a metà sensibile con l'impegno di rivedere in un secondo momento è una strategia buona.

Non farti chiamare paralisi. Sì, i nomi sono molto importanti ma non sono abbastanza importanti da sprecare enormi quantità di tempo. Se non riesci a trovare un buon nome in 10 minuti, vai avanti.


9

Se un buon nome non mi viene in mente, probabilmente mi chiedo se c'è un problema più profondo: la classe serve a uno scopo buono? Se lo è, nominarlo dovrebbe essere piuttosto semplice.


3

Se il tuo "FooProcessor" elabora davvero i foos, non essere riluttante a dargli quel nome solo perché hai già un BarProcessor, BazProcessor, ecc. In caso di dubbio, ovvio è meglio. Gli altri sviluppatori che devono leggere il tuo codice potrebbero non utilizzare lo stesso thesaurus che sei.

Detto questo, una maggiore specificità non farebbe male a questo particolare esempio. "Processo" è una parola piuttosto ampia. Ad esempio, è davvero un "FooUpdateProcessor" (che potrebbe diventare "FooUpdater")? Non devi essere troppo "creativo" riguardo al nome, ma se hai scritto il codice probabilmente hai un'idea abbastanza buona di cosa fa e cosa non fa.

Infine, ricorda che il semplice nome della classe non è tutto ciò che tu e i lettori del tuo codice dovete continuare - di solito ci sono anche spazi dei nomi in gioco. Questi possono spesso fornire ai lettori un contesto sufficiente per vedere chiaramente a cosa serve la tua classe, anche se il suo nome nudo è abbastanza generico.

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.