Sono immorale per l'utilizzo di un nome di variabile che differisce dal suo tipo solo per caso?


95

Ad esempio, prendi questo pezzo di codice:

var person = new Person();

o per voi Pythonistas:

person = Person()

Mi viene detto costantemente quanto sia grave, ma devo ancora vedere un esempio dell'immoralità di queste due righe di codice. Per me una persona è una persona e cercare di darle un altro nome è una perdita di tempo. Suppongo che nei giorni precedenti all'evidenziazione della sintassi, questo sarebbe stato un grosso problema. Ma oggigiorno è abbastanza facile distinguere il nome di un tipo dal nome di una variabile. Diamine, è anche facile vedere la differenza qui su SO.

O c'è qualcosa che mi manca? In tal caso, sarebbe utile fornire un esempio di codice che causa problemi.


Mi sono sempre chiesto questo. Bella domanda!
William Brendel,

18
Chiamare una persona persona è semplicemente crudele. Cosa c'è di sbagliato in "bob"?
Sam Meldrum,

17
Non dimentichiamo che prima di var c'era la bellezza zen di Person person = new Person ();
Jamie Ide

1
@ Jamie stai chiamando la digitazione statica in stile zen?
orokusaki

Vorrei approfondire anche un livello in questa domanda: è indiscutibilmente sbagliato fare Person Person=new Person();per questa materia? Come affermato in The Question, viviamo in tempi di tale incredibile evidenziazione della sintassi e riconoscimento del contesto che il mio compilatore non si è mai lamentato di me che facevo proprio questo. Adoro le mie variabili CamelCased - perché allora non dovrei (in situazioni in cui Person Personè un'istanza generale e unica della classe e nessun conflitto è presente né possibile)?
Robert Synoradzki

Risposte:


94

Qual è il ragionamento di coloro che ti dicono che questo è un male? Lo faccio tutto il tempo. È il modo più semplice ed espressivo per nominare una singola variabile di un tipo. Se avessi bisogno di due Personoggetti, potresti aggiungere un prefisso personad aggettivi significativi come

fastPerson
slowPerson

altrimenti solo

person

per me va bene.


8
"Qual è il ragionamento di quelli che ti dicono che questo è brutto?" - Non lo so. Ecco perché ho iniziato questo argomento. :-)
Jason Baker

Chiaramente non sei mai dovuto entrare nel codice di qualcun altro. So che quando vengo chiamato a ricercare un bug scoperto di recente in un codice vecchio di diversi anni da un programmatore che ha lasciato l'azienda da tempo, qualsiasi cosa che possa ostacolarmi è il momento di non risolvere il problema. Se uno di questi ostacoli sta cercando di capire cos'è un'istanza e cos'è una classe solo perché un programmatore non può essere disturbato a dire "var currentPerson = New Person ();" allora questo è tempo inutile, sprecato. ... e quando i tuoi clienti aspettano una soluzione, il tempo è essenziale.
David,

3
@David - Mi hai beccato! Sapevo che la codifica nel vuoto avrebbe sollevato la sua brutta testa prima o poi :) Seriamente, però - trovo difficile credere che tu possa inciampare non essendo in grado di discernere tra i tipi e le loro istanze in base a questa convenzione di denominazione.
Andrew Hare

2
@David - questo dovrebbe essere il problema per lo strumento di analisi del codice. Inoltre, ecco perché esiste la convenzione che i tipi iniziano con la lettera maiuscola in Python.
ilya n.

69

Uso molto questo modello nelle firme dei metodi. Se non sono in grado di fornire un nome descrittivo alternativo, IMHO, non c'è niente di sbagliato in questo.

Ciò che è sbagliato sarebbe se avessi due tipi di persona e persona, allora è molto molto sbagliato.


1
"Ciò che è sbagliato sarebbe se avessi due tipi di persona e persona, allora è molto molto sbagliato." - Questo ha perfettamente senso per me.
Jason Baker,

1
Se la tua creazione di un'API, VB non sarebbe in grado di gestire il codice poiché non fa distinzione tra maiuscole e minuscole.
JoshBerke

1
Ehi, nel caso di un'API sei infastidito dai nomi o dalle proprietà dei metodi pubblici, non dai nomi delle variabili, perché questi ultimi non saranno esposti al codice client. Per quanto riguarda la domanda di Jason, anch'io uso sempre questo nome. Assolutamente niente di sbagliato in questo.
Frederick The Fool

1
Esattamente il mio punto Frederick perché avere due tipi che differiscono solo per il caso di base è una cattiva idea ;-)
JoshBerke,

1
Anche se non è sbagliato, rende il codice più difficile da leggere. Anche la leggibilità è importante.
J3r3myK

45

Lo uso sempre per i riferimenti temporanei agli oggetti. Lo eviterei come la piaga dei tipi di dati primitivi.

Person person = new Person(); // okay

int Int = 42; // pure evil

Se davvero non ci fosse un significato semantico che potrei dare a una primitiva, userei i o s, a parte gli indici di loop non riesco a pensare a nessun altro scenario simile.
AnthonyWJones

1
Consiglierei di non usare i, soprattutto se stai scrivendo codice con un ciclo. i è quasi universalmente considerato come un nome di variabile di ciclo.
Jason Baker,

3
Concordato. Un nome di variabile di una sola lettera urla "Sono temporaneo". Gli indici dei cicli dovrebbero essere i, j, k, tutti gli altri dovrebbero essere a, b, c, x, y, z o qualsiasi altra lettera che non possa essere scambiata per qualcos'altro, come le o.
Bill the Lizard

Bravo! 42 è semplicemente troppo. :)
Vishal Seth

18

Se qualcuno dice che è malvagio, chiedigli se è meglio:

var abc = new Person();

2
@ Chris: esattamente! O meglio ancora: var temp = new Person();(Dichiarazione di non responsabilità: so che ci sono davvero posti per una volta usano variabili temporanee, ma spesso quando vedo questo nel codice di qualcuno, l'autore semplicemente non è mai riuscito a dare alla var un nome appropriato e potrebbe anche essere "abc".)
Dinah

15

Se la persona è una persona generale nel contesto, "persona" è davvero un buon nome. Ovviamente se la persona ha un ruolo specifico nel codice, è meglio nominarla usando il ruolo.


9

Suppongo che verrò svalutato per averlo detto, ma ...

Avendo appena passato un secolo assistendo a omicidi epici e avidità, noi programmatori siamo davvero benedetti se la cosa più immorale che possiamo fare è nominare una variabile.


6
In alternativa, se le decisioni morali che possiamo prendere sono così insignificanti, siamo maledetti. Non sono sicuro di volere che il mio elogio funebre si concentri sul mio stile di programmazione. Vorrei almeno un accenno di passaggio al mio essere parte di una famiglia.
David Thornley,

1
@ David: di nuovo a destra. Con il mio primo nipotino in arrivo, suppongo sia banale, ma mi interessa che tipo di mondo stiamo tramandando.
Mike Dunlavey

8

Non penso che sia necessariamente "cattivo", ma ovviamente se puoi qualificarlo per dargli più contesto, come che tipo di persona è (hai a che fare solo con una delle presumibilmente molte persone possibili), allora qualcun altro lo sceglie può capire meglio.


6

Jason - Non sono sicuro di chi ti abbia detto che questo è un male. Un certo numero di autori usa questo come un modo standard per esprimere un'istanza (minuscolo) di una classe (maiuscolo).

Lo uso abbastanza spesso poiché trovo che la variabile in minuscolo effettivamente mi comunica non solo che si tratta di un'istanza, ma anche il nome della classe.

A meno che qualcuno non abbia una solida argomentazione in contrario, continuerò sicuramente a farlo.


6

Il motivo per cui è considerato cattivo è che se hai bisogno di avere 2 persone in futuro, puoi quindi finire con un codice simile.

Persona persona = nuova persona ();

Persona persona2 = nuova persona ();

Sarebbe quindi al limite del "cattivo". Tuttavia, in quel caso dovresti poi rifattorizzare la tua persona originale per distinguere tra i due.

Come per il tuo esempio, il nome della variabile "persona" è un nome perfettamente descrittivo per l'oggetto "Persona". Quindi non c'è niente di sbagliato in questo.


3

Dico il nome per quello che è: se la variabile rappresenta una persona con 2 cani, chiamala personWith2Dogs. Se la variabile ha un ambito breve (come una variabile di ciclo), la persona va bene.


3

Lo uso molto nel mio codice e non credo che ci sia qualcosa di sbagliato in esso. Detto questo, io (probabilmente) non lo userei in un metodo più lungo, diciamo di una schermata, e se ci sono più istanze della classe Person. Sicuramente non nominarli person1, person2, person3 ... invece usa qualcosa di più descrittivo, come person_to_del, person_to_ban, person_to_update, ecc.


3

Non immorale, ma una ricerca globale troverà entrambi Persone personse non si attiva la distinzione tra maiuscole e minuscole. Preferisco un prefisso per rendere più facile la ricerca / sostituzione globale, ma assolutamente NON ungherese o qualcosa di lungo / complicato. Quindi, io uso ...

Personper la classe / tipo aPersonper una variabile locale thePersonper un parametro di metodo myPersonper una variabile di istanza ourPersonper una variabile di classe

In rare occasioni, potrei usarlo pin un contesto locale in cui ho MOLTI riferimenti, ma di solito si applica solo agli indici di loop e simili.


3

Dipende.

Se hai uno stile di capitalizzazione rigoroso, quindi le variabili iniziano in minuscolo (e usa under_scores o camelCase per le interruzioni di parola) e le classi iniziano con le lettere maiuscole, allora è ovvio che la persona è una variabile e la persona è una classe, e quando qualcuno lo capisce , non sembrano trovarsi in spazi dei nomi sovrapposti. (Allo stesso modo, le persone non si confondono quasi mai tra il verbo o il sostantivo "polacco" e l'aggettivo "polacco".)

Se non hai un tale stile, hai due nomi che possono essere facilmente confusi e differiscono solo nel caso. Questo è male.


Ciao di nuovo David. Non ricordo se sei tu quello che ha modificato uno dei miei messaggi perché avevo scritto "pollish", o era "lucido", quando volevo strofinare qualcosa finché non brilla? Vabbè, non sono ancora sicuro di quale sia giusto :-)
Mike Dunlavey,

Non credo di aver fatto una tale modifica, quindi probabilmente era qualcun altro. BTW, è "polacco".
David Thornley,

2

Quali sono gli argomenti esatti che queste persone usano?

Se non ti consentono di utilizzare persona come nome di variabile, potresti considerare di aggiungere il prefisso "a".

aPerson = Person()

2
Sarebbe peggio, secondo me. È più difficile da leggere e non fornisce alcuna informazione aggiuntiva.
Joachim Sauer

Sì, ma almeno il nome è diverso dal nome della classe, che è quello che vogliono ovviamente.
Gerrie Schenck,

Sarebbe seguire le lettere della legge, ma sicuramente non lo spirito.
Joachim Sauer

1
+1, utilizzo la persona per i parametri e la mia persona per i locali che gestisco.
Amy B

2

Penso che quello che stai facendo vada bene. Penso che in generale sia importante avere standard di codifica concordati.

Ad esempio io uso lowerCamelCase per istanze, variabili e UpperCamelCase per classi ecc

Gli standard di codifica dovrebbero eliminare questo problema.

Quando guardo programmi open source di successo, spesso hanno standard di codifica

http://drupal.org/coding-standards

http://help.joomla.org/content/view/826/125/

http://wiki.rubyonrails.org/rails/pages/CodingStandards

http://lxr.linux.no/linux/Documentation/CodingStyle

Concordare gli standard di codifica dovrebbe essere l'ultima battaglia che devi affrontare.

In effetti guarda la voce di wikipedia (da http://en.wikipedia.org/wiki/CamelCase )

Stile di programmazione e codifica

L'uso delle maiuscole interne è talvolta consigliato per indicare i confini delle parole dalle linee guida dello stile di codifica per la scrittura del codice sorgente (ad esempio, il linguaggio di programmazione Mesa e il linguaggio di programmazione Java). Le raccomandazioni contenute in alcune di queste linee guida sono supportate da strumenti di analisi statica che controllano l'aderenza del codice sorgente.

Queste raccomandazioni spesso distinguono tra UpperCamelCase e lowerCamelCase, specificando tipicamente quale varietà dovrebbe essere utilizzata per tipi specifici di entità: variabili, campi record, metodi, procedure, tipi, ecc.

Uno stile di codifica Java ampiamente utilizzato impone di utilizzare UpperCamelCase per le classi e lowerCamelCase per istanze e metodi. [19] Riconoscendo questo utilizzo, alcuni IDE, come Eclipse, implementano scorciatoie basate su CamelCase. Ad esempio, nella funzionalità di assistenza ai contenuti di Eclipse, digitare solo le lettere maiuscole di una parola CamelCase suggerirà qualsiasi nome di classe o metodo corrispondente (ad esempio, digitare "NPE" e attivare l'assistente ai contenuti potrebbe suggerire "NullPointerException").

La notazione originale ungherese per la programmazione specifica che un'abbreviazione minuscola per il "tipo di utilizzo" (non il tipo di dati) deve anteporre a tutti i nomi delle variabili, con il resto del nome in UpperCamelCase; come tale è una forma di lowerCamelCase. CamelCase è la convenzione ufficiale per i nomi dei file in Java e per il personal computer Amiga.

Microsoft .NET consiglia lowerCamelCase per parametri e campi non pubblici e UpperCamelCase (noto anche come "Pascal Style") per altri tipi di identificatori. [20]

Python consiglia UpperCamelCase per i nomi delle classi. [21]

Il registro NIEM richiede che XML Data Elements utilizzi UpperCamelCase e gli attributi XML utilizzino lowerCamelCase.

Non esiste una convenzione unica per l'inclusione di abbreviazioni maiuscole (principalmente acronimi e iniziali) nei nomi CamelCase. Gli approcci includono lasciare l'intera abbreviazione in maiuscolo (come in "useHTTPConnection") e lasciare solo la prima lettera in maiuscolo (come in "useHttpConnection").

Il case Camel non è affatto universale nell'informatica. Gli utenti di diversi linguaggi di programmazione moderni, in particolare quelli delle famiglie Lisp e Forth, usano quasi sempre trattini. Tra i motivi a volte addotti vi sono il fatto che ciò non richiede lo spostamento sulla maggior parte delle tastiere, che le parole sono più leggibili quando sono separate e che il caso del cammello potrebbe semplicemente non essere conservato in modo affidabile nelle lingue che non fanno distinzione tra maiuscole e minuscole (come ad esempio Common Lisp, che, sebbene tecnicamente sia un linguaggio che distingue tra maiuscole e minuscole, canonicalizza (piega) gli identificatori in maiuscolo per impostazione predefinita).


2

È possibile sostenere un argomento più forte che i nomi di metodi di quel tipo non solo sono innocui ma possono essere un indicatore di codice di buona qualità.

  • Un indicatore di una buona granularità del codice: se i metodi sono brevi, monouso e denominati in modo descrittivo, non sono necessarie molte informazioni nei nomi delle variabili. Se disponi di metodi lunghi che eseguono molte cose e devi tenere traccia di molto contesto e stato, i nomi delle variabili devono essere più descrittivi.

  • Un indicatore di calcoli generici che vengono trasferiti in metodi generici: se si esegue una manipolazione intermedia di strutture dati in un metodo aziendale, ad esempio deve essere deduplicato un array di utenti, sarà necessario avere variabili nell'ambito con nomi come users[]e deduplicatedUsers[]. Se si sposta la deduplicazione su un metodo di utilità, è possibile chiamare il metodo Utils.dedup(array)e chiamare l'array deduplicato deduplicatedArrayo semplicemente result.

  • I decompilatori Java spesso usano uno schema come quello per nominare le variabili locali (le variabili di istanza e di classe sono normalmente disponibili nel bytecode, ma le variabili locali no), e i risultati sono più leggibili di quanto ci si potrebbe aspettare, infatti spesso più leggibili del fonte originale.

  • Vedi il principio di Larry Wall di "Local Ambiguity is OK" - http://www.wall.org/~larry/natural.html .


2

Direi che probabilmente hai in mente un uso specifico ogni volta che crei un oggetto. Il tipo da solo riflette molto raramente tale uso.

Quindi, se desideri creare un nuovo contatto nella tua applicazione della rubrica, potresti voler chiamare la variabile newContact.

E se stai testando il tuo codice per controllare il comportamento di Personoggetti senza nomi impostati, potresti volerli chiamare unnamedPersono qualcosa di simile.

Chiamarlo semplicemente personrinuncia a una grande possibilità di rendere il tuo codice auto-documentante.


Chiamalo anonimo! :)) var anonymous = new Person (); O ancora meglio: var you_know_who = new Person (); :))
Vadim Ferderer

@Vadim Ferderer: var he_who_must_not_be_named = new Person();? :-)
Platinum Azure

2

Solo se stai programmando in VB6. In tal caso , quello che stai facendo è illegale, ma non immorale.


1

Lo faccio anche io, e non capisco nemmeno perché dovrebbe essere "immorale". Anche se posso capire che a volte può essere fonte di confusione, ma oggi abbiamo IDE con intellisense e evidenziazione della sintassi che assicureranno che (se commetti un errore e fai riferimento alla tua variabile anziché alla tua classe, e viceversa) vedere il tuo errore abbastanza velocemente. E abbiamo anche il compilatore. :)


1

Inoltre non vedo alcun problema con questa pratica. Finché c'è solo una variabile di quella classe, è facile da scrivere e di facile lettura. Imo, che si applica anche a un editor di testo di base. Personalmente non riesco a ricordare nessuno che lo definisca cattivo o addirittura immorale. Continua a farlo :)


1

Penso che la "regola" a cui potresti pensare sia intesa più per tipi primitivi e classi in cui il nome della classe fa un nome di variabile scadente.

Ad esempio, se avessi a che fare con il calcolo del costo di un particolare articolo in un negozio online, il seguente codice non sarebbe valido:

Decimal _decimal = item.BaseCost + item.Tax;

Invece, sarebbe consigliato un nome più descrittivo, come "_total" o "_cost".


1

L'unico problema con questo genere di cose che ho trovato è se vuoi lo stesso nome per un membro privato e anche una proprietà pubblica.

Se differiscono solo nel caso, funzionerà bene nei linguaggi con distinzione tra maiuscole e minuscole come C #, ma non in VB.NET.

Quindi, ad esempio, in VB, scriverei

Private _name As String

ma

Public Property Name() As String
    Get
        Return _name
    End Get
    Set(ByVal Value As String)
        _name = Value
    End Set
End Property

Farei lo stesso in C #, quindi la traduzione dall'uno all'altro è indolore. Inoltre lo rende un po 'meno soggetto a errori, dal momento che è molto facile leggere male, o addirittura sbagliare parole che differiscono solo per caso.


L'unica cosa che non mi piace di questo approccio è che le variabili con un prefisso di sottolineatura tendono ad essere associate a membri privati ​​di una classe. Ma suppongo che l'approccio generale sia decente.
Jason Baker,

Sì, questo è ciò che sto illustrando qui. La definizione di una variabile locale, come "Dim person as New Person" andrebbe bene. Molto (molto) occasionalmente con il compilatore VB, c'è un'ambiguità e la normale auto-capitalizzazione rassicurante non si verifica. È un buon segnale visivo che non va tutto bene.
ChrisA

1

Non immorale, ma se il nome migliore per la tua variabile è il nome del tipo, qualcosa non va o stai solo facendo una prova di concetto o qualcosa del genere. Per me un nome di variabile deve riferirsi al significato nel contesto aziendale e non al linguaggio di programmazione. Sarà più difficile capire il codice.


1

Uso spesso Person person = new Person()me stesso. Comunemente utilizzato in Java / C #.

Anche se ieri ho finito per chiedermi perché

private enum DataType {NEW, OLD}

non funziona in C # ...

Soprattutto vedendo come è possibile utilizzare String, string, Double, double, ... a volontà in C #.


enum supporta solo byte, sbyte, short, ushort, int, uint, long, ulong. cioè tipi di valore numerico non frazionario
Kev

1
Person person = new Person()

va bene nel mio libro.

Quando diventa orribile è quando hai:

string Person;
string person;

Molto facile mescolare i 2.


1

Ciò che mi è stato espresso, oltre a non soddisfare i nostri standard di codifica, è evitare di aggiungere confusione quando qualcun altro sta leggendo il mio codice. Io, personalmente, non vedo alcun problema, purché il significato sia chiaro.

Per quanto riguarda i tipi CLR (int, string, ecc.) Puoi usare String o string (ecc.) Per dichiarare il tipo, quindi eviterei di usare qualcosa di simile

int Int = 0;
string String = "hi there";

1

Rendere le maiuscole l'unica differenza è pericoloso ... continua a farlo per un grande progetto e ti garantisco che incapperai in errori bizzarri che non riesci a individuare.

fastPerson / slowPerson come sopra vanno bene ... sono descrittivi e differenziati dal nome del tipo di variabile ... ma dai amico, chiamare un int "Int" sarebbe semplicemente pigro.


1

Direi che non è mai immorale - è solo il nome della tua variabile di base. Se non riesci a pensare a un nome migliore, nominarlo dopo il suo tipo è un buon valore predefinito ( solo per i tipi complessi - per i tipi incorporati è malvagio ) e molte volte non c'è davvero un nome migliore perché non lo fai. Non so nient'altro sulla variabile. Come con questo metodo

void SaveToDatabase(Person person) {...}

L'unica cosa che potresti ragionevolmente chiamare persona è person_to_saveo qualcosa del genere che sembra ridondante.

Tuttavia in molti casi puoi migliorare la leggibilità del tuo codice sostituendo la persona con un nome più descrittivo. Ad esempio, questo è meno descrittivo

void AddToAccount(Account account, Person person)  {...}

di questo

void AddToAccount(Account account, Person dependent)  {...}

Tuttavia, per favore, per favore - piuttosto per favore non mettere una "a" o "t" davanti al nome del tipo. Vale a dire una persona per "una persona" o una persona per "la persona". È eccessivamente complicato e non aggiunge molto valore. Inoltre inizi a inquinare il tuo ambito con un mucchio di variabili che iniziano con a o t che possono ridurre al minimo il valore di intelli-sense.


Sono d'accordo con l'ultimo paragrafo. Non vedo alcun motivo per aggiungere caratteri estranei solo per evitare un problema di stile minore.
Jason Baker,

0

Non direi che è orribile. Di solito al nome della variabile faccio da prefisso "a" in questo genere di cose per mostrare che si tratta di una singola istanza del tipo, quindi lo farei

Person aPerson = new Person();

Rende il codice più naturale, credo.


0

Assolutamente niente di sbagliato in esso soggetto a caveat segnalati da altri (riassumendo qui per comodità): non farlo con tipi primitivi, refactoring dell'istanza originale se un'altra istanza viene aggiunta in seguito, non usare char-case per differenziare i nomi delle classi, ecc.

La mia regola pratica? Le dichiarazioni in codice dovrebbero essere lette come semplici frasi inglesi.

Persona persona = nuova persona ();

Dipendente dipendente = person.getRole (EMPLOYEE);

Genitore genitore = person.getRole (PARENT);

person.getFullName ();

dipendente.getSalary ();

parent.getChildren ();

parent.getFullName (); // assumendo che il motivo del decoratore sia in gioco

if (person.hasRole (EMPLOYEE)) {

  ...

}

E così via.

Se l'ambito della variabile è limitato (il metodo di incapsulamento è di 10-15 righe, per esempio) potrei anche usare "p" invece di "persona". I nomi di variabili più brevi rappresentano una distrazione minore quando cerchi di mantenere il contesto nella tua testa. Evita prefissi gratuiti come la notazione ungherese "a" o (rabbrividire) e le sue derivazioni. (Intendiamoci, non ho nulla contro tali prefissi se usati nel contesto appropriato - codice API C ++ / COM / ATL / Win32 ecc., Dove aiuta a mantenere le assegnazioni / typecasting dritto).

I miei due (!) Bit :-)

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.