Classi di denominazione - Come evitare di chiamare tutto un "<WhatEver> Manager"? [chiuso]


1188

Molto tempo fa ho letto un articolo (credo un post di blog) che mi ha messo sulla strada "giusta" per la denominazione degli oggetti: sii molto scrupoloso nel nominare le cose nel tuo programma.

Ad esempio, se la mia applicazione (come una tipica app aziendale) gestisse utenti, aziende e indirizzi, avrei una classe a User, a Companye una di Addressdominio - e probabilmente da qualche parte comparirebbero a UserManager, a CompanyManagere AddressManagera che gestiscono tali cose.

Così si può dire ciò che coloro UserManager, CompanyManagere AddressManagerfare? No, perché Manager è un termine molto generico che si adatta a qualsiasi cosa tu possa fare con i tuoi oggetti di dominio.

L'articolo che ho letto mi ha raccomandato di usare nomi molto specifici. Se si trattasse di un'applicazione C ++ e il UserManagerlavoro fosse quello di allocare e liberare gli utenti dall'heap, non li avrebbe gestiti ma salvaguardati la loro nascita e morte. Hmm, forse potremmo chiamarlo a UserShepherd.

O forse il UserManagercompito è quello di esaminare i dati di ciascun oggetto Utente e firmarli crittograficamente. Quindi avremmo un UserRecordsClerk.

Ora che questa idea mi è rimasta, provo ad applicarla. E trova questa idea semplice incredibilmente difficile.

Posso descrivere cosa fanno le classi e (purché non scivoli nella codifica veloce e sporca) le classi che scrivo fanno esattamente una cosa. Quello che mi manca per passare da quella descrizione ai nomi è una specie di catalogo di nomi, un vocabolario che associa i concetti ai nomi.

Alla fine mi piacerebbe avere qualcosa come un catalogo di modelli nella mia mente (spesso i modelli di progettazione forniscono facilmente i nomi degli oggetti, ad esempio una fabbrica )

  • Factory: crea altri oggetti (denominazione presa dal modello di progettazione)
  • Pastore - Un pastore gestisce la vita degli oggetti, la loro creazione e spegnimento
  • Sincronizzatore: copia i dati tra due o più oggetti (o gerarchie di oggetti)
  • Tata: aiuta gli oggetti a raggiungere lo stato "utilizzabile" dopo la creazione, ad esempio collegando altri oggetti

  • ecc ecc.

Quindi, come gestite questo problema? Hai un vocabolario fisso, inventi al volo nuovi nomi o pensi di nominare cose non così importanti o sbagliate?

PS: Sono anche interessato a link ad articoli e blog che trattano il problema. Come inizio, ecco l'articolo originale che mi ha fatto riflettere: nominare le classi Java senza un "Manager"


Aggiornamento: riepilogo delle risposte

Ecco un breve riassunto di ciò che ho imparato da questa domanda nel frattempo.

  • Cerca di non creare nuove metafore (Tata)
  • Dai un'occhiata a cosa fanno gli altri framework

Ulteriori articoli / libri su questo argomento:

E un elenco attuale di prefissi / suffissi di nome che ho raccolto (soggettivamente!) Dalle risposte:

  • Coordinatore
  • Costruttore
  • scrittore
  • Lettore
  • handler
  • Contenitore
  • Protocollo
  • Bersaglio
  • Converter
  • controllore
  • Visualizza
  • Fabbrica
  • Entità
  • Secchio

E un buon consiglio per la strada:

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


11
Appartiene alla wiki della comunità perché non esiste una risposta "migliore". È una discussione.
DOK,

13
Questo è contro intuitivo. Non dovrebbero chiamarlo un forum? Penserei che un wiki sarebbe per una raccolta di fatti, non opinioni.
AaronLS

78
Grazie per averlo aggiornato, ma l'ultimo consiglio è un consiglio terribile! Se non riesci a pensare a un buon nome in 10 minuti, probabilmente c'è qualcosa di sbagliato nella tua classe. (Con le avvertenze standard: 1) perfetto è il nemico del bene, 2) La spedizione è una caratteristica - ricorda solo che stai affrontando un debito tecnico.)
Jeff Sternal,

11
Se non riesci a trovare un buon nome in 10 minuti, chiedi aiuto al tuo collega. Non arrenderti.

9
Se non riesci a trovare un buon nome in 10 minuti, prova a spiegarlo ai tuoi colleghi; essi potrebbero pensare a un nome buono (user338195), ma cercando di spiegare che probabilmente aiuterà a scoprire cosa c'è di sbagliato con esso ( Jeff ).
WillC,

Risposte:


204

Ho fatto una domanda simile , ma dove possibile provo a copiare i nomi già nel framework .NET e cerco idee nei framework Java e Android .

Sembra Helper, Managere Utilsono i nomi inevitabili che attribuisci per coordinare le classi che non contengono stato e sono generalmente procedurali e statici. Un'alternativa è Coordinator.

Si potrebbe ottenere prosey particolarmente viola con i nomi e andare per le cose come Minder, Overseer, Supervisor, Administrator, e Master, ma come ho detto preferisco tenerlo come i nomi quadro a cui siete abituati.


Alcuni altri suffissi comuni (se questo è il termine corretto) che trovi anche nel framework .NET sono:

  • Builder
  • Writer
  • Reader
  • Handler
  • Container

4
Mi piacciono molto. Non cadono nella trappola di metafore cattive o sconosciute perché sono già in uso da .NET Framework. Potrebbe essere interessante esaminare anche altre librerie (Java) per ulteriori informazioni su ciò che viene comunemente utilizzato.
froh42,

Vorrei suggerire Conductor, come il direttore di un'orchestra musicale. È sicuramente un ruolo importante, a seconda della natura delle collaborazioni che devi "condurre" (altri oggetti sono attori molto specializzati che dovrebbero rispondere al comando centralizzato e non preoccuparti troppo di ogni altro collaboratore).
Heltonbiker,

1
Non credo che la soluzione per -er classi sia quella di trovare un nome diverso. Come ho letto in molti altri post e sto cercando di imparare la risposta, è che è necessario modificare l'architettura, non solo il nome utilizzato.
Michael Ozeryansky,

115

Puoi dare un'occhiata a source-code-wordle.de , ho analizzato lì i suffissi più usati dei nomi delle classi del framework .NET e alcune altre librerie.

I primi 20 sono:

  • attributo
  • genere
  • aiutante
  • collezione
  • convertitore
  • gestore
  • Informazioni
  • fornitore
  • eccezione
  • servizio
  • elemento
  • manager
  • nodo
  • opzione
  • fabbrica
  • contesto
  • articolo
  • progettista
  • base
  • editore

147
In una particolare compagnia molto tempo fa, conoscevo un ingegnere così stufo dell'assurda e crescente pletora di regole del suffisso che affliggevano la compagnia con cui finiva con aria di sfida ogni classe Thingy.

8
Questo elenco di nomi da solo non è così utile senza il contesto del quale dovrebbe essere applicato il suffisso.
Fred,

65

Sono tutto per buoni nomi e scrivo spesso sull'importanza di prestare molta attenzione nella scelta dei nomi per le cose. Per questa stessa ragione, sono diffidente nei confronti delle metafore quando nominerò le cose. Nella domanda originale, "fabbrica" ​​e "sincronizzatore" sembrano buoni nomi per ciò che sembrano significare. Tuttavia, "pastore" e "tata" non lo sono, perché si basano su metafore . Una classe nel tuo codice non può essere letteralmente una tata; la chiami una tata perché si prende cura di altre cose proprio come una tata nella vita reale si prende cura di neonati o bambini. Va bene nel discorso informale, ma non va bene (secondo me) per nominare le classi nel codice che dovranno essere mantenute da chi sa chi sa quando.

Perché? Perché le metafore dipendono dalla cultura e spesso anche dall'individuo. Per te, nominare una "tata" di classe può essere molto chiaro, ma forse non è così chiaro per qualcun altro. Non dovremmo fare affidamento su questo, a meno che tu non stia scrivendo codice che è solo per uso personale.

In ogni caso, la convenzione può creare o distruggere una metafora. L'uso della stessa "fabbrica" ​​si basa su una metafora, ma che esiste da un po 'di tempo ed è attualmente abbastanza conosciuta nel mondo della programmazione, quindi direi che è sicuro da usare. Tuttavia, "tata" e "pastore" sono inaccettabili.


10
Questo argomento si rompe davvero nel fatto che ovviamente la stessa Factory è una metafora. Spesso le metafore chiariranno davvero in cosa potrebbe essere utile un oggetto, mentre essere vaghi o generici assicura automaticamente che l'unico modo per capire cosa fa il codice è leggerlo completamente! Lo scenario peggiore.
Kzqai,

1
+1 per evitare nomi "carini". Penso che sia fantastico essere il più diretto possibile con il linguaggio. (Certo, non è sempre facile essere diretti, succinti, precisi e inequivocabili allo stesso tempo ...)
andrewf

1
Una scelta inventiva del verbo + "er" sarà di solito più chiara per le classi concrete di una colorata analogia. Nuove astrazioni, d'altra parte - cose che sono un nuovo concetto, un nuovo "genere di cose" piuttosto che solo una nuova "cosa" - spesso funzionano bene come metafore ("fagioli" di Java, "obiettivi" di Haskell, GUI "windows", "promesse" di molte lingue). Tuttavia, la maggior parte delle basi di codice non avrà invenzioni autentiche del genere.
Malnormalulo,

51

Potremmo fare senza xxxFactory, xxxManagero xxxRepositoryclassi se abbiamo modellato correttamente il mondo reale:

Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
        .Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
        .OfType<User>().CreateNew("John Doe");

;-)


11
Come raggiungeresti universi paralleli e dimensioni alternative?
tster,

23
È facile: Omniverse.Instance.Dimensions ["Il nostro"]. Universi ["Il nostro"]. Galassie ... ;-)
herzmeister,

73
Aggiornamento: questo è stato aggiunto in .NET 4.0:; Universe.Instance.ToParallel())
Connell

2
Tuttavia infrange la legge di Demeter!
Jonas G. Drange,

13
Quelli sono oggetti e membri, non nomi di classe
Harry Berry,

39

Sembra una pendenza scivolosa verso qualcosa che sarebbe stato pubblicato su thedailywtf.com, "ManagerOfPeopleWhoHaveMortgages", ecc.

Suppongo sia giusto che una classe Manager monolitica non sia una buona progettazione, ma l'uso di "Manager" non è male. Invece di UserManager potremmo suddividerlo in UserAccountManager, UserProfileManager, UserSecurityManager, ecc.

'Manager' è una buona parola perché mostra chiaramente che una classe non rappresenta una 'cosa' del mondo reale. "AccountsClerk" - come posso dire se si tratta di una classe che gestisce i dati degli utenti o che rappresenta qualcuno che è un impiegato degli account per il loro lavoro?


8
Che dire UserAccounter, UserProfiler e UserSecurer? Se ti sbarazzi di Manager, sei costretto a trovare la definizione specifica, che penso sia una buona cosa.
Didier A.

10
Che dire di Account utente, Profilo utente, Sicurezza utente o O?
Clime

3
Lo chiamerei "MortageOwnersManager"
volter9

A volte il dominio ha nomi specifici. Come "MortageHolder" che potrebbe essere migliore di "MortageOwner"
borjab


24

Quando mi trovo a pensare di usare Managero Helperin un nome di classe, lo considero un odore di codice che significa che non ho ancora trovato la giusta astrazione e / o sto violando il principio della singola responsabilità , quindi rifattorando e mettendo più impegno nella progettazione spesso rende la denominazione molto più semplice.

Ma anche le classi ben progettate non si nominano (sempre) da sole e le tue scelte dipendono in parte dal fatto che tu stia creando classi di modelli di business o classi di infrastrutture tecniche.

Le classi del modello di business possono essere difficili, perché sono diverse per ogni dominio. Ci sono alcuni termini che uso molto, come Policyper le classi di strategia all'interno di un dominio (ad esempio LateRentalPolicy), ma di solito derivano dal tentativo di creare un " linguaggio onnipresente " che puoi condividere con gli utenti aziendali, progettando e denominando le classi in modo che modellino - idee, oggetti, azioni ed eventi del mondo.

Le classi di infrastruttura tecnica sono un po 'più semplici, perché descrivono domini che conosciamo molto bene. Preferisco incorporare i nomi dei modelli di progettazione nei nomi delle classi, come InsertUserCommand, CustomerRepository,o SapAdapter.capisco la preoccupazione di comunicare l'implementazione anziché l'intento, ma i modelli di progettazione sposano questi due aspetti del design della classe - almeno quando si ha a che fare con l'infrastruttura, dove si desidera il il design dell'implementazione è trasparente anche mentre nascondi i dettagli.


1
Mi piace molto l'idea di utilizzare il Policysuffisso per le classi contenenti business logic
jtate

+1 per menzionare l'odore di codice associato a nomi come "Manager" e "Helper". Trovo che se non ho nomi chiari per le cose, di solito deriva almeno in parte da una certa confusione nella mia comprensione del dominio, sia commerciale che tecnica. Quasi equivalentemente, potrebbe significare che sto solo rompendo in modo reattivo le lezioni perché "sono diventate troppo grandi" - il che per me è anche un segno di modellazione inadeguata. Questa dovrebbe essere la risposta più votata.
nclark,

10

Essere al passo con i motivi definiti dal (diciamo) il libro GOF e nominare gli oggetti dopo questi mi porta molto a nominare i corsi, organizzarli e comunicare l'intento. Molte persone capiranno questa nomenclatura (o almeno una parte importante di essa).


Fowler è un buon riferimento per me, ma il GOF è una grande raccomandazione.
Lazzaro,

Perdona la mia ignoranza. A quale libro di Fowler ti riferisci?
Brian Agnew,


19
Hmm, a volte funziona (ad esempio come una fabbrica o una strategia) ma altre volte sento che questo comunica il modo di implementazione (ho usato uno schema!) Più che l'intento e il lavoro della classe. Ad esempio la cosa più importante di Singleton è ciò che rappresenta - e non che sia un Singleton. La denominazione così rigorosa in base ai modelli utilizzati sembra una denominazione rigorosa in base ai tipi utilizzati. Ad esempio la notazione ungherese applicata erroneamente dal gruppo di sistemi Windows (che descrive il tipo di dati C anziché "tipo di intento")
froh42

1
Per le classi di infrastruttura tecnica, di solito è auspicabile rendere l'implementazione trasparente - e la maggior parte dei nomi canonici del modello di progettazione comunicano sia l'implementazione che l'intento. Le classi del modello di dominio sono tuttavia un'altra questione.
Jeff Sternal,

10

Se non riesco a trovare un nome più concreto per la mia classe rispetto a XyzManager, questo sarebbe un punto per me da riconsiderare se questa è davvero funzionalità che appartiene insieme in una classe, cioè un "odore di codice" architettonico.


8

Penso che la cosa più importante da tenere a mente sia: il nome è abbastanza descrittivo? Puoi dire guardando il nome che cosa dovrebbe fare la Classe? L'uso di parole come "Manager", "Service" o "Handler" nei nomi delle classi può essere considerato troppo generico, ma poiché molti programmatori le usano, aiuta anche a capire a cosa serve la classe.

Io stesso ho usato molto il modello di facciata (almeno, penso che sia così che si chiama). Potrei avere una Userclasse che descrive un solo utente e una Usersclasse che tiene traccia della mia "raccolta di utenti". Non chiamo la classe a UserManagerperché non mi piacciono i manager nella vita reale e non voglio ricordarmeli :) L'uso del modulo plurale mi aiuta a capire cosa fa la classe.


Mi piace molto anche questo approccio perché semplifica l'idea di una gestione top-down degli oggetti. È più probabile che un gruppo di utenti implichi che il lavoro venga svolto tra gli utenti anziché dal UserManager in basso. Inoltre, avere un utente in possesso di un riferimento agli utenti non è strano come possedere UserManager. È più aperto al pensiero relativo, piuttosto che rigorosamente OOP.
Seph Reed,

Il problema con questo approccio è che diventa davvero difficile cercare il codice Users, soprattutto se si passa intorno all'oggetto manager. this.users = new Users()Ma poi invariabilmente da qualche altra parte nel codice si usersfarà riferimento a una matrice di Users.
Pupazzo di neve

Come dici tu, gli utenti implicano davvero una "raccolta di utenti" - una raccolta di entità che è stateful. Ma SRP significherebbe che non vorrai raggruppare la gestione utenti (funzionalità e logica aziendale) con i dati utente (stato). Non dicendo che ti sbagli, solo che UserManager è appropriato se la classe è responsabile della gestione degli utenti e non solo della memorizzazione del loro stato e del CRUD di base.
Richard Moore,

5

Specifico per C #, ho trovato "Linee guida per la progettazione di framework: convenzioni, modi di dire e schemi per librerie .NET riutilizzabili" per avere molte buone informazioni sulla logica della denominazione.

Per quanto riguarda la ricerca di quelle parole più specifiche, però, spesso uso un dizionario dei sinonimi e salto tra le parole correlate per cercare di trovarne una buona. Cerco di non spendere troppo tempo con esso, mentre progredisco attraverso lo sviluppo mi vengono in mente nomi migliori, o talvolta mi rendo conto che SuchAndSuchManagerdovrebbero davvero essere suddivisi in più classi, e quindi il nome di quella classe deprecata diventa un problema .


3

Credo che la cosa fondamentale qui sia di essere coerenti nell'ambito della visibilità del tuo codice, vale a dire fino a quando tutti coloro che hanno bisogno di guardare / lavorare sul tuo codice capiscono la tua convenzione di denominazione, allora dovrebbe andare bene, anche se decidi di chiamarli "CompanyThingamabob" e "UserDoohickey". La prima tappa, se lavori per un'azienda, è vedere se esiste una convenzione aziendale per la denominazione. Se non c'è o non lavori per un'azienda, crea i tuoi termini personali che hanno senso per te, passali in giro con alcuni colleghi / amici fidati che almeno codificano casualmente e incorpora qualsiasi feedback che abbia senso.

Applicare la convenzione di qualcun altro, anche quando è ampiamente accettato, se non ti sfugge di dosso, è un errore nel mio libro. Innanzitutto devo capire il mio codice senza fare riferimento ad altra documentazione ma allo stesso tempo deve essere abbastanza generico da non essere incomprensibile per qualcun altro nello stesso campo dello stesso settore.


1
Tuttavia, una convenzione coerente, anche se leggermente non intuitiva, è meglio che avviare la propria convenzione. Le persone che lavorano su un progetto impareranno molto rapidamente qualsiasi convenzione coerente e presto dimenticheranno che la funzionalità non è esattamente ciò che ci si potrebbe aspettare a prima vista.
Mr. Boy,

@John, è esattamente quello che ho detto. La convenzione deve essere accettata dal gruppo e se lavori in un'azienda, verifica se esiste una convenzione aziendale. Per l'azienda sto pensando a qualsiasi gruppo, che si tratti di un team di progetto open source o di una vasta collezione di programmatori. Se tutti prendessero ciò che era disponibile che si adatta quasi alle loro esigenze, penso che ci mancherebbe molto l'innovazione.
Lazzaro,

2

Considererei i modelli che stai usando per il tuo sistema, le convenzioni di denominazione / catalogazione / raggruppamento di classi di tende da definire in base al modello usato. Personalmente, mi attengo a queste convenzioni di denominazione in quanto sono il modo più probabile per un'altra persona di essere in grado di raccogliere il mio codice ed eseguirlo.

Ad esempio UserRecordsClerk potrebbe essere meglio spiegato estendendo un'interfaccia RecordsClerk generica che sia UserRecordsClerk che CompanyRecordsClerk implementano e poi si specializzano, il che significa che si possono esaminare i metodi nell'interfaccia per vedere a cosa servono / sono generalmente le sue sottoclassi.

Vedi un libro come Design Patterns per informazioni, è un libro eccellente e potrebbe aiutarti a chiarire dove stai mirando a stare con il tuo codice - se non lo stai già usando! ; o)

Immagino che fino a quando il tuo modello sia ben scelto e usato per quanto è appropriato, allora i nomi delle classi abbastanza semplici e poco inventivi dovrebbero essere sufficienti!


Ho commentato questo sulla risposta di Brian Agnew. Non credo che i nomi dei modelli facciano nomi di buone classi solo in alcuni casi (Fabbrica, Strategia) ma non in altri (Singleton). Voglio che i nomi riflettano il lavoro della classe e non il modo in cui l'ho implementato.
froh42,
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.