risposta-alla-domanda-sullo-sviluppo-web-bd.com

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

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

Ad esempio se la mia applicazione fosse (come tipica app di business) gestendo utenti, società e indirizzi avrei un User, un Company e una Address classe di dominio - e probabilmente da qualche parte un UserManager, un CompanyManager e un AddressManager potrebbero apparire come maniglie quelle cose.

Quindi puoi dire che cosa fanno UserManager, CompanyManager e AddressManager? 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 raccomandava l'uso di nomi molto specifici. Se si trattava di un'applicazione C++ e il lavoro UserManager stava allocando e liberando gli utenti dall'heap, non gestiva gli utenti ma ne custodiva la nascita e la morte. Hmm, forse potremmo chiamarlo UserShepherd.

O forse il lavoro di UserManager consiste nell'esaminare i dati di ciascun utente User e firmare i dati crittograficamente. Quindi avremmo un UserRecordsClerk.

Ora che questa idea mi è rimasta, cerco di applicarla. E trova questa semplice idea incredibilmente difficile.

Posso descrivere che cosa fanno le classi e (a patto che non scivoli nella codifica rapida 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 mappa i concetti ai nomi.

In definitiva mi piacerebbe avere nella mia mente qualcosa di simile a un catalogo di modelli (spesso i modelli di progettazione forniscono facilmente i nomi degli oggetti, ad esempio a fabbrica)

  • Fabbrica: crea altri oggetti (nomi presi dal modello di progettazione)
  • Pastore - Un pastore gestisce la vita degli oggetti, la loro creazione e chiusura
  • Synchronizer - 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 tramite il cablaggio ad altri oggetti

  • ecc ecc.

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

P.S .: Sono anche interessato a link ad articoli e blog che parlano del problema. Per cominciare, ecco l'articolo originale che mi ha fatto riflettere: Denominare classi Java senza un 'Manager'


Aggiornamento: riepilogo delle risposte

Ecco un piccolo 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 corrente di prefissi/suffissi di nome che ho raccolto (soggettivamente!) Dalle risposte:

  • Coordinatore
  • Costruttore
  • Scrittore
  • Lettore
  • Handler
  • Contenitore
  • Protocollo
  • Bersaglio
  • Converter
  • Controllore
  • Vista
  • 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 sprecare enormi quantità di tempo. Se non riesci a trovare un buon nome tra 10 minuti, vai avanti.

1074
froh42

Ho chiesto 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, Manager e Util sono i nomi inevitabili che si allega per le classi di coordinamento che non contengono stati e sono generalmente procedurali e statici. Un'alternativa è Coordinator.

Potresti ottenere una prosa particolarmente viola con i nomi e cercare cose come Minder, Overseer, Supervisor, Administrator e Master, ma come ho detto preferisco tenerlo come i nomi delle strutture a cui sei abituato.

Alcuni altri suffissi comuni (se questo è il termine corretto) si trovano anche nel framework .NET:

  • Builder
  • Writer
  • Reader
  • Handler
  • Container
178
Chris S

Puoi dare un'occhiata a source-code-wordle.de , ho analizzato i suffissi più frequentemente 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
107
Markus Meyer

Sono tutto per un buon nome e spesso scrivo sull'importanza di prestare molta attenzione quando scelgo i nomi delle cose. Per questo stesso motivo, sono diffidente nei confronti delle metafore quando si nominano le cose. Nella domanda iniziale, "factory" e "synchronizer" sembrano buoni nomi per quello che sembrano significare. Tuttavia, "pastore" e "bambinaia" non lo sono, perché sono basati su metafore . Una classe nel tuo codice non può essere letteralmente una bambinaia; la chiami tata perché si prende cura di altre cose molto simili a una tata della vita reale che si occupa dei bambini o dei bambini. Va bene nel discorso informale, ma non OK (a mio parere) 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 dipendono anche dall'individuo. Per te, nominare una "bambinaia" di classe può essere molto chiaro, ma forse non è così chiaro a qualcun altro. Non dovremmo fare affidamento su questo, a meno che tu non stia scrivendo un codice che è solo per uso personale.

In ogni caso, la convenzione può creare o distruggere una metafora. L'uso della "fabbrica" ​​stessa è basato su una metafora, ma che è in circolazione da un bel po 'ed è attualmente abbastanza noto nel mondo della programmazione, quindi direi che è sicuro da usare. Tuttavia, "bambinaia" e "pastore" sono inaccettabili.

60
CesarGon

Potremmo fare a meno delle classi xxxFactory, xxxManager o xxxRepository se modelliamo il mondo reale correttamente:

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

;-)

46
herzmeister

Sembra una pendenza scivolosa per qualcosa che potrebbe essere pubblicato su thedailywtf.com, "ManagerOfPeopleWhoHaveMortgages", ecc.

Suppongo sia giusto che una classe Manager monolitica non sia di buon design, ma usare 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 dovrei dire se questa è una classe che gestisce i dati degli utenti, o rappresenta qualcuno che è un impiegato di contabilità per il loro lavoro?

35
Mr. Boy

Dato che sei interessato agli articoli in quest'area, potresti essere interessato all'articolo di Steve Yegge "Execution in the Kingdom of Nouns":

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html

23
stusmith

Quando mi trovo a pensare di usare Manager o Helper in 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 di responsabilità singola , quindi refactoring e mettendo più impegno nel design spesso rende più facile la denominazione.

Ma anche le classi ben progettate non si nominano (sempre) da sé e le tue scelte dipendono in parte dalla creazione di classi di modelli di business o classi di infrastrutture tecniche.

Le classi dei modelli di business possono essere difficili, perché sono diverse per ogni dominio. Ci sono alcuni termini che uso molto, come Policy per le classi di strategia all'interno di un dominio (ad esempio, LateRentalPolicy), ma di solito derivano dal tentativo di creare un " ubiquitous language " che puoi condividere con gli utenti business, progettando e denominare le classi in modo da modellare idee, oggetti, azioni ed eventi del mondo reale.

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

19
Jeff Sternal

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

10

Essere au fait con i pattern definiti da (dire) il GOF book , e nominare gli oggetti dopo questi mi aiuta molto a nominare le classi, organizzandole e comunicando l'intento. La maggior parte delle persone capirà questa nomenclatura (o almeno una parte importante di essa).

9
Brian Agnew

Penso che la cosa più importante da tenere a mente sia: il nome è abbastanza descrittivo? Puoi dire guardando il nome cosa dovrebbe fare la Classe? Usare parole come "Manager", "Servizio" o "Gestore" nei nomi delle classi può essere considerato troppo generico, ma dal momento che molti programmatori li usano aiuta anche a capire a cosa serve la classe.

Io stesso ho usato molto il modello di facciata (almeno, penso che sia quello che si chiama). Potrei avere una classe User che descrive solo un utente e una classe Users che tiene traccia della mia "raccolta di utenti". Non chiamo la classe a UserManager perché non mi piacciono i manager nella vita reale e non voglio essere ricordato a loro :) Semplicemente usando il plurale mi aiuta a capire cosa fa la classe.

7
Droozle

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

Per quanto riguarda invece la ricerca di parole più specifiche, uso spesso un thesaurus e salta le parole correlate per cercare di trovarne una buona. Cerco di non passare troppo tempo con esso, mentre progredisco durante lo sviluppo con nomi migliori, o talvolta mi rendo conto che SuchAndSuchManager dovrebbe essere suddiviso in più classi, e quindi il nome di quella classe deprecata diventa un non- problema.

5
AaronLS

Credo che la cosa fondamentale qui sia di essere coerenti nell'ambito della visibilità del tuo codice, cioè finché 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 si lavora per un'azienda, è necessario crearne di propri usando termini che hanno senso per te, trasmetterli ad alcuni colleghi/amici fidati che almeno codificano casualmente e incorporare qualsiasi feedback che abbia senso.

Applicare la convenzione di qualcun altro, anche quando è ampiamente accettato, se non salta fuori dalla pagina è un errore nel mio libro. Prima di tutto ho bisogno di 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 nello stesso settore.

2
Lazarus

Prenderò in considerazione i pattern che stai utilizzando per il tuo sistema, le convenzioni di denominazione/catalogazione/raggruppamento di classi di tende da definire con il modello utilizzato. Personalmente, mi attengo a queste convenzioni di denominazione in quanto sono il modo più probabile per un'altra persona di essere in grado di prendere il mio codice e correre con esso.

Ad esempio, UserRecordsClerk potrebbe essere meglio spiegato come estensione di un'interfaccia generica RecordsClerk che sia UserRecordsClerk che CompanyRecordsClerk implementano e quindi si specializzano, il che significa che si possono esaminare i metodi nell'interfaccia per vedere a cosa servono in genere le 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à utilizzando! ; O)

Suppongo che, a condizione che il tuo schema sia scelto e utilizzato per quanto è appropriato, allora i nomi di classe semplici e non intuitivi dovrebbero essere sufficienti!

2
Caroline