Чи є коли-небудь сенс для рефактора в кінцевому рахунку з більш високою LOC? [зачинено]


25

Чи бувають випадки, коли більше деталізований код (як у більш логічних висловлюваннях) чистіший, ніж більш стислий код?



18
Звичайно, так і є. Навіть при усуненні дублювання код для визначення нової вилученої функції займає власний простір. Написання нової функції може зайняти чотири рядки і зберегти лише два, і все-таки робити це варто.
Кіліан Фот

5
"більш стислий код"? Я дуже ненавиджу помилкове переконання, що менший підрахунок рядків означає "кращий" код. Це не так. Насправді, як правило, навпаки. Наступає момент - і це досягається дуже швидко - де набивання все більше і більше сенсу все менше і менше простору робить код важче зрозуміти. Насправді існує цілий конкурс - Міжнародний конкурс з прихованих кодів С -, коли багато переможців покладаються на ці межі людського розуміння, щоб написати непроникний код.
Ендрю Генле

1
Назва вашого запитання та саме ваше запитання задають різні запитання. Наприклад, оператор if може бути змінений на потрійний вираз, який є логічним, але лише 1 рядок.
Капітан Людина

1
-1 *** більше деталізованого коду (як у більш логічних висловлюваннях) *** Багатослівність та кількість логічних висловлювань - це дві не пов'язані між собою речі. Погано змінювати визначення.
Пітер Б

Відповіді:


70

Щоб відповісти на це, давайте візьмемо приклад із реального світу, який трапився зі мною. У бібліотеці C #, яку я підтримую, у мене був такий код:

TResult IConsFuncMatcher<T, TResult>.Result() =>
    TryCons(_enumerator) is var simpleMatchData && !simpleMatchData.head.HasValue
        ? _emptyValue.supplied
            ? _emptyValue.value
            : throw new NoMatchException("No empty clause supplied");
        : _recursiveConsTests.Any() 
            ? CalculateRecursiveResult() 
            : CalculateSimpleResult(simpleMatchData);

Обговорюючи це з однолітками, одностайним вердиктом було те, що вкладені потрійні вирази в поєднанні з "розумним" вживанням is varпризвели до лаконічного, але важкого для читання коду.

Тому я відновив це на:

TResult IConsFuncMatcher<T, TResult>.Result()
{
    var simpleMatchData = TryCons(_enumerator);

    if (!simpleMatchData.head.HasValue)
    {
        return _emptyValue.supplied
            ? _emptyValue.value
            : throw new NoMatchException("No empty clause supplied");
    }

    return _recursiveConsTests.Any() 
        ? CalculateRecursiveResult() 
        : CalculateSimpleResult(simpleMatchData);
}

Оригінальна версія містила лише один складений вираз із неявним return. Нова версія тепер містить явну декларацію змінної, ifзаяву та два явні returns. Він містить більше висловлювань та більше рядків коду. Однак усі, з ким я консультувався, вважали, що це легше читати та міркувати, що є ключовими аспектами "чистого коду".

Тож відповідь на ваше запитання - це чітке "так", більш багатослівний може бути більш чистим, ніж стислий код, і таким чином є дійсним рефакторингу.


34
У цей день і вік мізки розробника є дефіцитнішим ресурсом, ніж пропускна здатність диска, процесора, оперативної пам’яті чи мережі. Ті , інші речі мають важливе значення, і в деяких випадках вони можуть бути вашим обмежуючим фактором, але в більшості випадків, ви хочете , щоб оптимізувати здатність ваших розробників , щоб зрозуміти код першої , а потім ці інші речі.
anaximander

2
@anaximander, абсолютно згоден. Напишіть код, щоб інші люди читали перше, а компілятор - друге. Ось чому я вважаю корисним, щоб інші перевіряли мій код, навіть якщо я єдиний, хто його розробляє.
Девід Арно

4
Якщо я переглядав це, я б запропонував змінити порядок повернення заяв та усунути його !з умови. Я б також запропонував поставити друге повернення в else. Але навіть, як і зараз, це масове вдосконалення.
Мартін Боннер підтримує Моніку

2
@DavidArno Я бачу цю логіку, і якщо if (!foo.HasValue)це ідіома у вашому коді, ще сильніше. Однак ifце не на самому ділі вихід бистротвердеющий - це «робити це або що в залежності.»
Мартін Боннер підтримує Моніку

2
@fabric Порівняння булевих значень небезпечно. Я уникаю цього, наскільки я можу.
Мартін Боннер підтримує Моніку

30

1. Відсутність кореляції між LOC та якістю коду.

Мета рефакторингу - покращити якість фрагмента коду.

LOC - це дуже базовий показник, який іноді співвідноситься з якістю коду: наприклад, метод, що має кілька тисяч LOC, може мати проблеми з якістю. Слід зазначити, однак, що LOC - не єдина метрика, і у багатьох випадках бракує кореляції з якістю. Наприклад, метод 4 LOC не обов'язково є більш читабельним або більш ремонтованим, ніж метод 6 LOC.

2. Деякі методи рефакторингу складаються з додавання LOC.

Якщо ти береш до переліку методів рефакторингу , ви можете легко помітити ті, які полягають у навмисному додаванні локальних місць. Приклади:

Обидва є дуже корисними методами рефакторингу, і їх вплив на LOC абсолютно не має значення при розгляді того, використовувати їх чи ні.

Уникайте використання LOC.

LOC - небезпечний показник. Це дуже просто виміряти і дуже важко правильно інтерпретувати.

Поки ви не ознайомитесь з методиками вимірювання якості коду, по-перше, уникайте вимірювання LOC. Більшу частину часу ви не отримаєте нічого актуального, і трапляться випадки, коли це введе вас в оману до зниження якості вашого коду.


Ви відновили свою відповідь та покращили якість, додавши більше ЛОТ (рядків тексту): p
посмішка

12

Якщо ви хочете побачити кінцевий результат просто мінімізувати кількість байтів або номер локального коду вашого вихідного коду, перегляньте подання на сайт Golf Stack Exchange Code. .

Якщо ваш вихідний код таким чином зменшиться, незабаром у вас виникне незрозумілий безлад. Навіть якщо ви людина, яка написала такий код, і зрозуміла його повністю на той час, наскільки ефективними ви будете, коли повернетесь до нього через півроку? Немає жодних доказів того, що такий мінімальний код насправді виконується і швидше.

Код повинен бути написаний таким чином, щоб будь-який член вашої команди міг поглянути на нього та зрозуміти, що він робить.


Можливо, зайве, але просто прописати це; якщо ви рефакторний код для гольфу для читабельності, ви завжди отримуєте більше LoC
JollyJoker

1

Так, рефакторинг, безумовно, може призвести до отримання більше рядків коду.

Найпоширеніший випадок IMO - це коли ви берете код, який не є загальним, і ви робите його більш загальним / гнучким . Генеризуючий код легко змушує рядки коду значно збільшуватися (іноді в два рази і більше).

Якщо ви очікуєте, що нещодавній загальний код буде використаний іншими (а не як внутрішній компонент програмного забезпечення) як бібліотека, ви, як правило, додаєте код unittest та розмітку документації в коді, що знову збільшить рядки коду.

Наприклад, ось дуже поширений сценарій, який відбувається у кожного розробника програмного забезпечення:

  • ваш продукт потребує термінової нової пріоритетної функції або виправлення або покращення помилок протягом двох тижнів (або будь-який термін вважається терміновим для вашого проекту, розміру / розміру компанії / тощо)
  • ви наполегливо працюєте і вчасно доставляєте XYZ, і це працює. Вітаємо! Чудова робота!
  • Поки ви розробляли XYZ, ваш існуючий дизайн / реалізація коду насправді не підтримував XYZ, але ви змогли зафіксувати XYZ у кодовій базі
  • проблема полягає в тому, що лайм некрасивий і має жахливий кодовий запах, тому що ви робили якісь хитрі / розумні / потворні / погані практики, але якісь-такі роботи
  • коли ви знайдете час пізніше, ви перефактуруєте код, який може змінити багато класів або додати новий шар класів, і ваше нове рішення "зроблено правильно" і більше не має поганого запаху коду ... однак це робити "правильний шлях" тепер займає більше рядків коду.

Деякі конкретні приклади, які приходять до мене з голови

  • для інтерфейсу командного рядка у вас може бути 5000 рядків if / else - якщо код або ви можете використовувати зворотні дзвінки ... кожен зворотний виклик був би набагато меншим і простішим для читання / тестування / перевірки / налагодження / тощо, але якщо рахувати рядки кодуйте потворних 5000 рядків if / else - якщо код, ймовірно, буде меншим
  • для фрагмента коду обробки, який підтримує N методів обробки , ви знову можете використовувати оператори if / else, які виглядатимуть найпотворніше ...
    • або ви можете перейти на зворотній зв'язок, що було б приємніше / краще, але зворотні дзвінки займають більше рядків коду (хоча час компіляції)
    • або ви можете абстрагуватися далі та робити плагіни, які можна змінити під час виконання. плагіни хороші тим, що вам не доведеться перекомпілювати основний продукт для кожного нового плагіна чи модифікації до наявного плагіна. і ви можете опублікувати API, щоб інші могли поширити продукт. Але знову-таки плагін-підхід використовує більше рядків коду.
  • для GUI ви створюєте чудовий новий віджет
    • Ви або колега зазначаєте, що новий віджет буде чудовим для XYZ та ABC, але зараз віджет тісно інтегрований лише для роботи в XYZ
    • ви відновлюєте віджет для роботи обох, але тепер загальний рядок коду збільшується
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.