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




naming in java (11)

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 una tipica app di business) gestendo utenti, società e indirizzi avessi un User , una Company e una classe di dominio Address - e probabilmente da qualche parte un UserManager , un CompanyManager e un AddressManager apparirebbero come maniglie quelle cose.

Quindi puoi dire 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 di 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 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 quello che fanno le classi e (a patto che 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 sorta 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 una fabbrica )

  • Fabbrica: crea altri oggetti (nome preso dal modello di progettazione)
  • Pastore - Un pastore si occupa della vita degli oggetti, della loro creazione e dello spegnimento
  • 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 collegando ad altri oggetti

  • ecc ecc

Quindi, come gestisci questo problema? Hai un vocabolario fisso, inventi nuovi nomi al volo o consideri che nominare cose non importanti o sbagliate?

PS: 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: riassunto 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 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 avere 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.


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

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 ad una classe, ad esempio un "odore di codice" architettonico.


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

Per quanto riguarda la ricerca di quelle parole più specifiche, uso spesso un dizionario dei sinonimi e salta attraverso 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.


Sono tutto per un buon nome e spesso scrivo sull'importanza di prestare molta attenzione quando scelgo i nomi per le 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" ​​è basato su una metafora, ma è già in circolazione da un po 'di tempo ed è attualmente abbastanza noto nel mondo della programmazione, quindi direi che è sicuro da usare. Tuttavia, "bambinaia" e "pastore" sono inaccettabili.


Essere au fait con i pattern definiti da (diciamo) il libro GOF 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).


Suona come una china scivolosa a 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?


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 un UserManager perché non mi piacciono i manager nella vita reale e non voglio essere ricordato a loro :) Usare semplicemente la forma plurale mi aiuta a capire cosa fa la classe.


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

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

;-)


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ù sforzo nel design spesso rende più facile la denominazione.

Ma anche le classi ben progettate non si nominano (sempre) se stesse 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 la Policy per le classi di strategia all'interno di un dominio (ad esempio, LateRentalPolicy ), ma questi di solito LateRentalPolicy dal tentativo di creare un " linguaggio ubiquitario " che è possibile condividere con gli utenti aziendali, progettando e denominando le classi in modo che 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. Comprendo la preoccupazione di comunicare l'implementazione anziché l'intenzione, ma i modelli di progettazione sposano questi due aspetti del design di classe, almeno quando si ha a che fare con l'infrastruttura, in cui si desidera che la progettazione dell'implementazione sia trasparente anche mentre si nascondono i dettagli.


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 lavori per un'azienda, creane di tuoi usando termini che hanno senso per te, passali intorno ad alcuni colleghi / amici fidati che almeno codificano casualmente e incorporano 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.


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 che Helper , Manager e Util siano i nomi inevitabili che si attribuiscono ai corsi di coordinamento che non contengono uno stato e sono generalmente procedurali e statici. Un'alternativa è il Coordinator .

Potresti ottenere una prosa particolarmente viola con i nomi e andare per 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




naming