Nazewnictwo: Czy powinieneś poświęcić zwięzłość dla przejrzystości?

11

Na przykład następująca funkcja przechodzi przez tablicę, która zawiera nazwę i błędy pola wejściowego. Robi to, sprawdzając nazwę pola sprawdzania poprawności, a następnie wypychając informacje o błędzie do tablicy niepoprawnych pól.

Czy lepiej jest streścić i napisać to:

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 })
  }
},

Czy może być bardziej szczegółowy w ten sposób?

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 })
  }
},
alex
źródło
1
powiązane (być może duplikat): Czy istnieje wymówka dla krótkich nazw zmiennych?
komar
Nie mam ochoty pisać odpowiedzi, ale zawsze staramy się znaleźć dobry kompromis między długością nazwy a wyrazistością. Krótkie nazwy mogą być oczywiste dla pierwotnego programisty, ale nie dla wszystkich innych. Długie nazwy mogą sprawić, że kod będzie trudny do odczytania. Pomiędzy jest kompromis.
MetalMikester
1
potrzebuje więcej komentarzy
Ewan
Uwaga dodatkowa i nie jestem pewien, czy jest to możliwe w kodzie, ale jeśli nieprawidłowe pola itp. Byłyby przechowywane w mapie , a nie w tablicy , kod ten stałby się znacznie prostszy.
user949300
1
@alex W odpowiedzi na Twój komentarz: Jeśli możesz zdobyć lub wypożyczyć kopię Eloquent JavaScript autorstwa Marijn Haverbeke, (wersja 2014), przejdź na strony 73-75, aby zobaczyć świetny przykład użycia mapy zamiast tablicy. Mam nadzieję, że to pomaga.
user949300

Odpowiedzi:

23

Jeśli zwięzłość można poświęcić dla przejrzystości, powinna. Ale jeśli gadatliwość można poświęcić dla przejrzystości, jeszcze lepiej.

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 })
  }
},

Gdy zmienna żyje tylko tak długo, jak jedna linia, może być bardzo krótka. FoundInvalidFieldjest używany w trzech liniach i jest przedmiotem niniejszej pracy. Zasługuje na nazwę wyjaśniającą.

Jak zawsze kontekst jest królem.

candied_orange
źródło
2
+1 za „Jeśli zwięzłość można poświęcić dla przejrzystości, powinna. Ale jeśli gadatliwość można poświęcić dla przejrzystości, jeszcze lepiej”. Nawet gdy dążę do jasności prawie w każdej okoliczności. Ale to zdecydowanie cytat.
Tulains Córdova
12

Właściwie faworyzuję twój pierwszy przykład kodu.

Oczywiste jest, co robi kod, czytając go. Utrzymując nazwy zmiennych tak małe, jak to możliwe, czynisz kod jeszcze łatwiejszym do odczytania. Bardziej opisowe nazwy zmiennych byłyby konieczne tylko wtedy, gdyby twoje funkcje były dłuższe, twoje zmienne były liczniejsze i / lub zmienne zostały użyte w większym zakresie kodu.

Dzieje się tak dlatego, że masz krótkie funkcje, dlatego możesz także utrzymywać krótkie nazwy zmiennych. Wszystkie inne rzeczy są równe, zawsze mniej kodu jest zawsze lepsze.

Robert Harvey
źródło
2
W tym celu z zasady preferuję mniejsze nazwy zmiennych dla moich metod / funkcji. Jedynym czasem, gdybym użył bardziej pełnej nazwy, jest konflikt przestrzeni nazw. Jeśli jednak twoja funkcja jest niewielka, łatwiej jest to osiągnąć.
rozjaśnia
4
Pracowałem z kimś, kto był naprawdę duży w pełnych nazwiskach. zmienne i nazwy metod były w zasadzie pełnymi angielskimi zdaniami, np. theResultOfMethodDoFooWithBar. Pomysł polegał na tym, że miało to wyjaśnić sprawę, ale sprawiło mi to ból głowy podczas próby przeanalizowania (mentalnie) całego tego puchu. W tym przykładzie wiemy już, że metoda dotyczy sprawdzania poprawności pól. Nie ma innych parametrów „polowych”. Użycie nazwy takiej jak „validatingField” nie dodaje żadnej przejrzystości i zaciemnia ważne informacje podczas przeglądania.
JimmyJames
@unflores Też próbuję to zrobić. validatingFieldssą polami formularza z walidacją. Pierwotna nazwa to fieldWithValidation. Naprawdę trudno znaleźć krótką nazwę dla tego. Mógłbym to nazwać, fieldale wtedy będzie miał konflikt z innym fieldwewnątrz metody.
alex
4

Wydaje mi się, że zgadzam się z wujem Bobem, że wolę jasność bez nadmiernej gadatliwości . W pokazanych przykładach powiedziałbym, że zamiary drugiego są wyraźniejsze, bez nadmiernej gadatliwości . Łatwiej byłoby również znaleźć ten konkretny fragment podczas przeszukiwania bazy kodu w poszukiwaniu invalidFieldniż value.


Cóż, cytuję tutaj Clean Code (pomiń go, jeśli masz dość kazań wuja Boba (których nie jestem):

Użyj nazw ujawniających intencje

Łatwo powiedzieć, że imiona powinny ujawniać zamiary. Chcemy wywrzeć na tobie wrażenie, że poważnie podchodzimy do tego. Wybór dobrych nazw wymaga czasu, ale oszczędza więcej niż zajmuje. Uważaj więc na swoje imiona i zmieniaj je, gdy znajdziesz lepsze. Każdy, kto czyta Twój kod (łącznie z tobą), będzie szczęśliwszy.


Unikaj dezinformacji

Programiści muszą unikać pozostawiania fałszywych wskazówek, które zaciemniają znaczenie kodu. Powinniśmy unikać słów, których zakorzenione znaczenia różnią się od naszych


Dokonaj znaczących rozróżnień

Programiści tworzą problemy dla siebie, pisząc kod wyłącznie w celu zaspokojenia kompilatora lub interpretera.


Użyj przeszukiwalnych nazw

Użyj nazw, które pomogłyby ci zrobić grep -iIR whateveryouaresearching . (nie czysty kod, tutaj CC mówiło tylko o zmiennych jednoliterowych).


Unikaj mapowania mentalnego

Czytelnicy nie powinni tłumaczyć mentalnie twoich imion na inne, które już znają. Ten problem ogólnie wynika z wyboru, aby nie używać ani problematycznych terminów domeny, ani terminów domen rozwiązania.


Użyj problemowych nazw domen

Jeśli nie ma „programisty” dla tego, co robisz, użyj nazwy z domeny problemowej. Przynajmniej programista, który utrzymuje Twój kod, może zapytać eksperta domeny, co to znaczy.


Tulains Córdova
źródło
1

W dzisiejszych czasach zawsze wolałbym być bardziej opisowy - uzupełnianie kodu IDE oznacza, że ​​nie będziesz musiał pisać opisowych nazw zmiennych, więc nie widzę minusów.

Już w prehistorii obowiązywały ograniczenia nazw zmiennych, a używanie znaczących nazw zmiennych mogło w rzeczywistości wiązać się z mierzalnym kosztem (np. W BBC BASIC przy użyciu liczb całkowitych zmiennych statycznych% itp. Było o wiele tańsze niż użycie znaczącej liczby całkowitej - i w systemie z 1MHz procesor, co pozwala zaoszczędzić kilka cykli zegara w pętli)

Mcottle
źródło
6
Minusem nie jest to, że trzeba dużo pisać. Pisanie odbywa się tylko raz. Wadą zbyt długich nazw jest to, że czytanie staje się trudniejsze. Jest to podstępne, ponieważ czytanie odbywa się wiele razy w ciągu całego okresu użytkowania kodu, a także dlatego, że ludzie nie zauważają świadomie źródła problemu, ponieważ czytanie jest tak głęboko zakorzenione.
Kilian Foth
A jeśli musisz spędzać czas i zmiany kontekstu, próbując zapamiętać coś o zmiennej, ponieważ nie była wystarczająco opisowa, będzie cię to kosztować więcej czasu :).
mcottle,
1

Drugi wariant sprawia, że ​​jestem zaskoczony. Kiedy patrzę tylko na podpis, zastanawiam się, czy pole jest już znane jako nieważne? Czy też najpierw zostanie sprawdzony (jak się nazywa validatingField), aby sprawdzić, czy jest naprawdę nieważny? Więc to nie tylko zbędne informacje tutaj, dodatkowe informacje wydają się nieco mylące. Ten rodzaj „jasności” nie jest wyraźniejszy, wręcz przeciwnie.

Właściwie, kiedy zobaczyłem twoją pierwszą funkcję, również mnie to zaskoczyło. Zadałem sobie pytanie, dlaczego, do cholery, twoja funkcja zajmuje tylko pole, ale potem go nie używa i szuka innego w invalidFields? Szukanie pola wydaje się mieć dużo więcej sensu, gdy podana jest tylko nazwa pola, jak poniżej:

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 })
  }
}

Myślę jednak, że Bob Martin prawdopodobnie poszedłby o krok dalej i uczyniłby kod bardziej szczegółowym - dla większej przejrzystości - w innym kierunku. Typowe refaktoryzacja w stylu książki „Czysty kod” prawdopodobnie wyglądałoby tak:

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

z trzema dodatkowymi funkcjami

  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)
  }

Dyskusyjne jest, jeśli opłaca się posunąć się tak daleko za zasadą pojedynczej odpowiedzialności. Ma w rzeczywistości pewne zalety i wady. Moim osobistym punktem widzenia jest to, że oryginalny kod jest „wystarczająco czysty” dla większości kodu produkcyjnego, ale kod zrestrukturyzowany jest lepszy.

Kiedy wiedziałem, że muszę dodać coś do pierwszego wariantu, aby rosło coraz bardziej, wcześniej podzieliłem to na mniejsze funkcje, aby kod nawet nie zaczął się bałaganić.

Doktor Brown
źródło
validatingFieldsto pola w formularzu, które mają sprawdzanie poprawności. Początkowo nazwałem je, fieldsWithValidationale było to trochę długie.
alex
0

Ogólnie nie ma poprawnej odpowiedzi w nazewnictwie. Wiele osób, gdy otrzyma dokładnie ten sam zestaw zadań, będzie bardzo różnie nazywać wynikowe funkcje i zmienne. Oczywiście chcesz, aby inni, którzy czytają Twój kod, zrozumieli, ale dłużej nie zawsze oznacza, że ​​coś jest wyraźniejsze. Jeśli twój kod jest gęstszy, to musi nim być, to zajmie więcej czasu, aby zrozumieć, że nawet każda linia twoich funkcji jest tak przejrzysta i opisowa, jak to tylko możliwe.

Osobiście bardziej podoba mi się ten pierwszy przykład. Jest prosty i do tego stopnia, że ​​zmienne nie mają tak opisowych nazw, jak w drugim przykładzie. Szczerze mówiąc, nazwy zmiennych w drugim przykładzie nie są o wiele jaśniejsze niż pierwsze, moim zdaniem, a krótka funkcja ułatwia zrozumienie samej funkcji.

Pod koniec dnia, co będzie lepsze, zależy od ciebie i od tego, z kim pracujesz. W końcu to on będzie go czytał i utrzymywał.

Dom
źródło