Denominazione: dovresti sacrificare la sintassi per chiarezza?

11

Ad esempio, la funzione seguente scorre attraverso un array che contiene il nome e gli errori di un campo di input. Lo fa controllando il nome del campo di convalida e quindi spingendo le informazioni sull'errore nell'array di campi non valido.

È meglio essere brevi e scrivere questo:

addInvalidField (field, message) {
  const foundField = this.invalidFields.find(value => {
    return value.name === field.name
  })
  const errors = foundField.errors
  if (!errors.some(error => error.name === message)) {
    errors.push({ name: message, message })
  }
},

O essere più specifico in questo modo?

addInvalidField (validatingField, message) {
  const foundField = this.invalidFields.find(invalidField => {
    return validatingField.name === invalidField.name
  })
  if (!foundField.errors.some(foundFieldError => foundFieldError.name === message)) {
    fouldField.errors.push({ name: message, message })
  }
},
    
posta alex 30.11.2016 - 04:21
fonte

6 risposte

23

Se la brevità può essere sacrificata per chiarezza, dovrebbe. Ma se la verbosità può essere sacrificata per chiarezza, ancora meglio.

addInvalidField (field, message) {
  const foundInvalidField = this.invalidFields.find(x => x.name === field.name)
  if (!foundInvalidField.errors.some(x => x.name === message)) {
    foundInvalidField.errors.push({ name: message, message })
  }
},

Quando una variabile vive solo fino a una riga, può essere davvero molto breve. FoundInvalidField è utilizzato in tre righe ed è al centro di questo lavoro. Merita un nome esplicativo.

Come sempre, il contesto è il re.

    
risposta data 30.11.2016 - 05:31
fonte
13

In realtà preferisco il tuo primo esempio di codice.

È chiaramente evidente ciò che il codice fa solo leggendolo. Mantenendo i nomi delle variabili il più piccoli possibile, rendi il codice ancora più facile da leggere. Nomi di variabili più descrittivi sarebbero necessari solo se le tue funzioni fossero più lunghe, le tue variabili fossero più numerose e / o le variabili fossero usate su un ambito di codice più ampio.

È perché hai mantenuto le tue funzioni brevi che puoi anche mantenere i nomi delle variabili brevi. A parità di condizioni, meno codice è sempre migliore.

    
risposta data 30.11.2016 - 05:23
fonte
4

Penso di essere d'accordo con lo zio Bob su preferendo la chiarezza senza incorrere in eccessiva verbosità . Negli esempi che mostri, direi che l'intento del secondo è più chiaro senza incorrere in eccessiva verbosità . Inoltre, sarebbe più facile trovare quel particolare frammento quando cerchi il codice base per invalidField rispetto a value .

Bene sto citando Clean Code qui (salta se sei stufo della predicazione di zio Bob (che non sono):

Use Intention-Revealing Names

It is easy to say that names should reveal intent. What we want to impress upon you is that we are serious about this. Choosing good names takes time but saves more than it takes. So take care with your names and change them when you find better ones. Everyone who reads your code (including you) will be happier if you do.

Avoid Disinformation

Programmers must avoid leaving false clues that obscure the meaning of code. We should avoid words whose entrenched meanings vary from our

Make Meaningful Distinctions

Programmers create problems for themselves when they write code solely to satisfy a compiler or interpreter.

Use Searchable Names

Utilizza nomi che ti aiutino a fare un grep -iIR whateveryouaresearching . (non un codice pulito, qui CC parla solo di variabili a lettera singola).

Avoid Mental Mapping

Readers shouldn’t have to mentally translate your names into other names they already know. This problem generally arises from a choice to use neither problem domain terms nor solution domain terms.

Use Problem Domain Names

When there is no “programmer-eese” for what you’re doing, use the name from the problem domain. At least the programmer who maintains your code can ask a domain expert what it means.

risposta data 30.11.2016 - 13:59
fonte
1

Preferisco sempre essere più descrittivo in questi giorni: il completamento del codice IDE significa che non dovrai scrivere nomi descrittivi delle variabili in modo da non vedere uno svantaggio.

Ritornando alla preistoria avevi restrizioni del nome variabile e l'uso di nomi di variabili significativi poteva effettivamente comportare un costo misurabile (ad esempio nel BBC BASIC usando le variabili statiche intere A% ecc. era molto più economico che usare un intero significativo - e in un sistema con un processore da 1 MHz, il risparmio di alcuni cicli di clock in un loop contava davvero)

    
risposta data 30.11.2016 - 05:16
fonte
1

La seconda variante sembra essere perplessa. Quando guardo solo la firma, mi chiedo se il campo è già noto come non valido? O verrà prima convalidato (come si chiama validatingField ), per scoprire se è davvero non valido? Quindi qui non sono solo informazioni ridondanti, le informazioni extra sembrano essere in qualche modo fuorvianti. Questo tipo di "chiarezza" non è più chiaro, è il contrario.

In realtà, quando ho visto la tua prima funzione, mi ha anche lasciato perplesso. Mi sono chiesto perché diavolo fa la tua funzione solo a prendere un campo, ma poi non lo usa e ne cerca un altro in invalidFields ? Cercare un campo sembra avere molto più senso quando c'è solo un fieldname, come questo:

addInvalidField (fieldname, message) {
  const foundField = this.invalidFields.find(value => {
    return value.name === fieldname
  })
  const errors = foundField.errors
  if (!errors.some(error => error.name === message)) {
    errors.push({ name: message, message })
  }
}

Tuttavia, penso che Bob Martin probabilmente farebbe un passo in più e renderebbe il codice più dettagliato - per maggiore chiarezza - in una direzione diversa. Un tipico refactoring sulla falsariga del libro "Codice pulito" probabilmente assomiglia a questo:

addInvalidField (fieldname, message) {
  const foundField = findInvalidField(fieldName)
  addMessageForInvalidField(foundField,message)
}

con tre funzioni aggiuntive

  findInvalidField(fieldname){
    return this.invalidFields.find(value => { return value.name === fieldname })
  }

  addMessageForInvalidField(field,message){
    const errors = field.errors
    if (!doesErrorsContain(message)) {
      errors.push({ name: message, message })
    }
  }

  doesErrorsContain(message){
     return errors.some(error => error.name === message)
  }

È discutibile se vale la pena di andare così lontano con il principio della responsabilità unica. Ha in realtà alcuni pro e contro. Il mio punto di vista personale è che il codice originale è "abbastanza pulito" per la maggior parte del codice di produzione, ma il refactored è migliore.

Quando sapevo di dover aggiungere qualcosa alla prima variante in modo che aumentasse sempre di più, lo suddividerei in precedenza in queste funzioni più piccole, quindi il codice non inizierà nemmeno a diventare un disastro.

    
risposta data 30.11.2016 - 17:43
fonte
0

Non c'è una risposta corretta in generale nella denominazione. Molte persone, quando hanno lo stesso identico insieme di compiti, chiameranno le funzioni e le variabili risultanti in modo molto diverso. Ovviamente vuoi che gli altri leggano il tuo codice per capire, ma più a lungo non significa sempre che qualcosa è più chiaro. Se il tuo codice è più denso, allora deve essere necessario, allora ci vorrà più tempo per capire anche ogni linea delle tue funzioni è chiara e descrittiva come può essere.

Personalmente, mi piace di più il primo esempio. È lineare e al punto anche se le variabili non hanno nomi descrittivi come nel secondo esempio. Onestamente, i nomi delle variabili nel secondo esempio non sono molto più chiari del primo a mio parere e mantenendo la funzione breve è più facile capire la funzione stessa.

Alla fine della giornata, che è meglio dipenderà da te e da chiunque tu stia lavorando. Dopotutto, è chi lo leggerà e lo manterrà.

    
risposta data 30.11.2016 - 06:22
fonte

Leggi altre domande sui tag