I nomi delle variabili possono corrispondere ai nomi dei campi? [chiuso]

1

Microsoft ha suggerito che i nomi delle variabili non devono corrispondere ai nomi dei campi . Tuttavia ho visto questo in modo estensivo in Java (ad esempio, questo tutorial ), in particolare in setter e costruttori. Quindi, tra questi due stili:

public class Class {
    private int var;

    public void set(int var) { this.var = var; }
    public int get() { return var; }
}

o

public class Class {
    private int var;

    public void set(int varIn) { var = varIn; }
    public int get() { return var; }
}
  1. In generale, quale è il preferito?
  2. Dipende dal linguaggio (Java, C ++, C #, ecc.)?

modifica

Grazie a tutti, ma non mi preoccupo molto di Ruby e Objective-C, dove è chiaro (una convenzione di codifica o solo la sintassi). AFAIK, non c'è una convenzione ampiamente accettata su questo in Java e C ++ ed è per questo che sono preoccupato. (In C # dovremmo probabilmente seguire Microsoft senza un ragionamento?)

    
posta Franklin Yu 27.02.2016 - 05:10
fonte

5 risposte

1

Qui fai molte domande diverse.

Can variable names match field names?

Dipende dalla lingua. In alcuni, possono. In alcuni, ma l'uno può oscurare l'altro. In alcuni, non possono.

Generally speaking, which one is prefered?

Dipende dalla lingua. O, più precisamente, sugli standard di codifica di ogni particolare organizzazione, che sarà, tuttavia, spesso ispirata dallo standard di codifica della comunità della lingua (se ne esiste uno).

Does it depends on language (Java, C++, C#, etc.)?

Sì.

In Ruby, ad esempio, è possibile che getter e setter assomiglino a questo, e alcune persone preferiscono questo stile:

class Foo
  def bar
    @bar
  end

  def bar=(bar)
    @bar = bar
  end
end

I, e alcuni altri preferiscono questo stile:

class Foo
  def bar
    @bar
  end

  def bar=(val)
    @bar = val
  end
end

Si noti, tuttavia, che questa domanda si presenterà molto meno spesso di quanto si pensi, perché ogni programmatore Ruby che si rispetti non scriverebbe un codice così ripetitivo a mano ma invece lo sintetizza:

class Class
  def generate_getter(*names)
    names.each do |name|
      define_method(name) do
        instance_variable_get(:"@#{name}")
      end
    end
  end

  def generate_setter(*names)
    names.each do |name|
      define_method(:"#{name}=") do |val|
        instance_variable_set(:"@#{name}", val)
      end
    end
  end

  def generate_getter_and_setter(*names)
    generate_getter(*names)
    generate_setter(*names)
  end
end

class Foo
  generate_getter_and_setter :bar
end

In realtà, questo modello è così comune, che questi metodi vengono effettivamente spediti come parte della libreria principale sotto i nomi di Module#attr_reader , Module#attr_writer e Module#attr_accessor :

class Foo
  attr_accessor :bar
end

In Java, OTOH, sembra essere molto comune scrivere in realtà ogni getter e setter per intero, non importa quanto banale, e non generarli o sintetizzarli. Quindi, la domanda si presenta molto più spesso, e quindi è molto più probabile che ci saranno standard di codifica che la governano. In particolare, se la maggior parte dei tuoi getter e setter sono insignificanti, allora il potenziale di confusione è piuttosto basso (in che modo puoi confonderti in un metodo che è solo una singola linea banale?), E quindi, è più accettabile usare il stesso nome per il parametro del setter e il campo di supporto:

void setBar(X bar) { this.bar = bar; }

Questo è un pattern che è facilmente riconoscibile, e dal momento che ci sono così tanti setter insignificanti, i programmatori sono addestrati per questo modello, e quindi possono individuarlo anche in setter più grandi, più complessi e non banali.

OTOH, in C #, i getter e i setter banali vengono solitamente generati automaticamente, quindi gli unici in cui la scelta del nome del parametro è importante non sono banali, e quindi il potenziale di confusione è maggiore, e i programmatori non lo sono usato così tanto:

X Bar { get; set; } // auto-generated, trivial, programmer doesn't care

E nel caso di un setter non banale, la lingua effettivamente prescrive il nome del parametro (o, più precisamente, non c'è parametro , piuttosto, c'è una parola chiave speciale value , che valuta il valore passato al setter), quindi l'unica scelta è su come denominare il campo di supporto. Per questo, non ci sono linee guida, dal momento che gli standard di codifica si applicano solo al codice pubblicamente visibile (cioè public e protected membri) ei campi di supporto dovrebbero essere private (altrimenti, perché hanno getter e setter?). Tuttavia, poiché i campi dovrebbero essere denominati camelCase e le proprietà dovrebbero essere denominate PascalCase , non possono esserci conflitti tra di esse. (Questo è diverso in un linguaggio insensibile alle maiuscole e minuscole come VB.NET, ad esempio!)

private X bar;

X Bar
{
    get { return bar; }
    set { bar = value; }
}

o

private X _bar;

X Bar
{
    get { return _bar; }
    set { _bar = value; }
}

Questi due sembrano essere gli stili predominanti nella comunità .NET. Entrambi in realtà violano alcuni standard di denominazione ( Non nominare identificatori solo nel caso e Non utilizzare caratteri di sottolineatura ), ma tali standard si applicano solo agli identificatori pubblici, che il campo base non lo è. Poiché ampie parti di .NET sono ora open source, è effettivamente possibile vedere quali standard di denominazione Microsoft usa internamente e sembrano preferire il secondo (prefisso di sottolineatura). Ecco un esempio dalle .NET Concurrent Collections, che sono un'aggiunta piuttosto nuova a .NET e quindi dovrebbero riflettere gli standard di codifica abbastanza recenti :

private int _boundedCapacity;

public int BoundedCapacity
{
    get
    {
        CheckDisposed();
        return _boundedCapacity;
    }
}
    
risposta data 27.02.2016 - 13:27
fonte
1

La maggior parte se non tutte le lingue lo consentono.

È considerato una cattiva pratica perché rende confuso il codice - perché denominare due cose che sono diverse le stesse?

Ad esempio se si dispone di una classe di radiatore con un campo denominato temperatura e si desidera un metodo che controlli se la temperatura del radiatore è superiore alla temperatura ambiente corrente, che si passa, è meglio avere isWarmer (roomTemperature) che isWarmer (temperatura) perché non vuoi che temperatura e temperatura si riferiscano a due cose diverse quando sono entrambe rilevanti per il comportamento del metodo.

Con i costruttori oi metodi setter ha senso chiamarli allo stesso modo perché l'unico punto del metodo è assegnare un parametro a un campo della classe.

    
risposta data 27.02.2016 - 16:21
fonte
0

I compilatori standard * per C ++, Java e C # consentono di nascondere un campo con un parametro o una variabile. In tutte e tre le lingue, la parola chiave this oi modificatori di classe (in caso di campi statici) possono consentire l'accesso ai campi nascosti. Quindi sì, è possibile che tu abbia lo stesso nome per campi e variabili / parametri in queste lingue almeno in queste tre lingue.

Alcuni (me compreso) considerano il campo nascondendo una pratica pericolosa e pericolosa. Ho visto diversi bug sottili in cui le persone finiscono per impostare / leggere la variabile / campo errato. Queste cose tendono ad accadere di più con progetti mal testati o quando più sviluppatori hanno lavorato sullo stesso file con un intervallo considerevole. Alcuni progetti su cui ho lavorato impongono diverse convenzioni di denominazione per campi, parametri e variabili, riducendo così le possibilità di occultamento accidentale del campo. Ci sono modi per far rispettare anche questo (checkstyle / resharper).

Tuttavia, alcuni altri non considerano questa una cattiva pratica. Sostengono che i nomi delle variabili dovrebbero indicare ciò che rappresentano e i suffissi / i prefissi si aggiungono alla confusione. Puoi anche fare in modo che questo approccio funzioni, purché applichi una buona disciplina di test e altri che lavorano su questo progetto trovino questa pratica comoda con cui lavorare.

Alla fine della giornata, l'unica cosa che conta è la coerenza delle linee guida sullo stile e il livello di comfort del tuo team nel lavorare con loro. Non c'è nulla di più sinistro di una linea guida che le persone odiano - influenzerà la loro produttività e potrebbe aumentare la loro motivazione a bypassare queste pratiche.

* Per completezza, devo menzionare che è possibile per le persone modificare / modificare i compilatori per vietare questo comportamento .

    
risposta data 27.02.2016 - 11:15
fonte
0

In Objective-C, esiste una convenzione di codifica abbastanza strong che le variabili di istanza dovrebbero iniziare con un carattere di sottolineatura e le proprietà corrispondenti (getter e setter in altre lingue) non hanno la proprietà. Se segui queste convenzioni, quindi

_value = 0; // Assigns instance variable of 'self'
self.value = 0; // Calls setter method
[self setValue:0]; // Calls setter method, old-fashioned
value = 0; // Sets a local or global variable named value

Quindi qualunque cosa tu scriva, tutti vedono immediatamente qual è. D'altra parte, se guardi lo stackoverflow alle domande dei principianti, puoi scommettere che non usano queste convenzioni di codifica e che i bug sono causati dall'assegnazione ad alcune variabili locali e quindi non riescono a capire perché una variabile di istanza non sia cambiato.

    
risposta data 27.02.2016 - 15:16
fonte
0

La semplice risposta è che la moda è cambiata.

Scrivo ancora:

private int number;
//runs a method
public void Method(int number)
{
    this.number = number;
}

Che era un modo popolare di fare le cose.

Dove la nuova moda è:

int _number;
public void RunMethod(int number)
{
    _number = number;
}

Il secondo ha meno caratteri, che sia più chiaro o meno soggettivo.

    
risposta data 27.02.2016 - 17:00
fonte

Leggi altre domande sui tag