Clean Code коментарі до документації про клас


83

Я маю деякі дискусії з новими колегами щодо коментування. Нам обом подобається « Чистий код» , і я прекрасно розумію те, що слід уникати вбудованих коментарів до коду та використовувати назви класів та методів, щоб виразити те, що вони роблять.

Однак я великий шанувальник додавання резюме малого класу, який намагається пояснити мету класу та те, що насправді представляє, насамперед, щоб легко було підтримувати схему принципу єдиної відповідальності . Я також звик додавати однорядкові резюме до методів, які пояснюють, що метод повинен робити. Типовий приклад - простий метод

public Product GetById(int productId) {...}

Я додаю наступний підсумок методу

/// <summary>
/// Retrieves a product by its id, returns null if no product was found.
/// </summary

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

Однак мої колеги вважають, що подібні коментарі є " кодовим запахом " і що "коментарі - це завжди невдачі" ( Роберт К. Мартін ).

Чи є спосіб висловити та передати ці знання без додавання коментарів? Оскільки я великий фанат Роберта К. Мартіна, я трохи заплутався. Чи резюме збігається з коментарями і тому завжди провалюється?

Це не питання про внутрішні коментарі.


38
Роберт Мартін сказав: "Коментарі - це завжди невдачі"? Ну, тоді він є бахромою екстреміст, і його слід приймати з дрібкою солі. (Так, я знаю, що він пише так для риторичних цілей, щоб передати його повідомлення. Моя думка, так і слід .)
Кіліан Фот

18
Книги дядька Боба повинні бути з мішком солі на 1 кг ...
AK_

6
Якщо ви слідкуєте за Робертом Мартіном, документація для нульового випадку має бути тестом. Тобто у вас повинен бути тест, який показує, в якому випадку метод може повернути нуль. Крім того, оскільки це Java, анотація @Nullable також буде кращою за коментар.
Мартін Епш

15
@Bjorn Я маю копію чистого коду, і я читав її обкладинку, щоб вона охоплювала не один раз. Так, дядько Боб віддає перевагу коду як самодокументування, але в книзі є кілька прикладів коментарів до його власного коду . Справа в тому, що якщо ви відчуваєте вимушеність писати коментар, постарайтеся дуже змінити код, а не додавати коментар, але не забороняйте коментарі повністю (навіть в прямому коментарі).

6
Метод має бути названий TryGetById, а коментар слід видалити.
usr

Відповіді:


116

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

Враховуючи це, ми можемо застосувати той самий принцип DRY . Чи коментар говорить те саме, що і підпис? Давайте розглянемо ваш приклад:

Отримує продукт за його ідентифікатором

Ця частина просто повторює те, що ми вже бачимо з назви GetByIdплюс тип повернення Product. Це також ставить питання про те, у чому різниця між "отримання" та "отримання", і який кодовий код порівняно з коментарем має це розрізнення. Тож марно і трохи заплутано. Якщо що, це перешкоджає дійсно корисній, другій частині коментаря:

повертає null, якщо жодного товару не знайдено.

Ах! Це те, що ми точно не можемо знати точно з підпису і надає корисну інформацію.


Тепер зробіть це крок далі. Коли люди говорять про коментарі, як пахне кодом, питання не в тому, чи потрібен кодекс, як потрібен коментар, а в тому, чи вказує коментар, що код можна було б написати краще, щоб висловити інформацію в коментарі. Ось що означає "запах коду" - це не означає "не робіть цього!", Це означає, "якщо ви це робите, це може бути ознакою проблеми".

Тож якщо ваші колеги скажуть вам, що цей коментар про null - це кодовий запах, вам слід просто запитати їх: "Гаразд, як я повинен це висловити?" Якщо у них є здійсненна відповідь, ви щось дізналися. Якщо ні, то, ймовірно, їхні скарги будуть вбиті мертвими.


Щодо цього конкретного випадку, як правило, нульове питання, як відомо, є складним. Існує причина, чому бази коду містяться охоронними статтями, чому перевірка нуля є популярною умовою кодових контрактів, чому існування нуля називають "помилкою в мільярд доларів". Не так вже й багато життєздатних варіантів. Один популярний, проте, знайдений у C # - це Try...конвенція:

public bool TryGetById(int productId, out Product product);

В інших мовах може бути ідіоматичним використовувати тип (який часто називають чимось на кшталт Optionalабо Maybe) для позначення результату, який може бути або не бути там:

public Optional<Product> GetById(int productId);

Таким чином, ця позиція проти коментарів дістала нас десь: ми принаймні задумалися над тим, чи є цей коментар запахом, і які альтернативи можуть існувати для нас.

Чи слід насправді віддавати перевагу цим над оригінальним підписом - це зовсім інша дискусія, але у нас, принаймні, є варіанти висловлення коду, а не коментарі, що відбувається, коли жодного товару не знайдено. Вам слід обговорити з колегами, який із цих варіантів вони вважають кращим і чому, і, сподіваємось, допомогти перейти поза рамки догматичних тверджень щодо коментарів.


9
Або Linq-еквівалентно з Try..., ...OrDefault, повертають default(T)якщо пропозиція призведе до порожнього результату.
Барт ван Неєроп

4
Я дуже вдячний за вашу відмінність між вбудованими кодами-коментарями та коментарями до документації та наведеними прикладами :)
Рейчел

2
Можливі значення повернення функції повинні бути видно підписом. TryGetValueКартина є розумним способом зробити це в C #, але більшість функціональних мов є кращий спосіб представлення відсутнього значення. Детальніше читайте тут
AlexFoxGill

2
@BenAaronson: Якщо потрібно мати загальний інтерфейс, який може підтримувати коваріацію, його можна використовувати або T TryGetValue(params, ref bool success)для будь-якого типу T, або T TryGetValue(params)з нульовим вказівкою на відмову, для обмеженого класом типу T, але TryGetXXшаблон, який повертається, boolне сумісний з коваріацією.
supercat

6
У Java 8 ви можете повернути а, Optional<Product>щоб вказати, що не може бути продукту, повернутого з методу.
Вім Деблауве

102

Цитата Роберта К. Мартіна виймана з контексту. Ось цитата з трохи більше контексту:

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

Коментарі не схожі на Список Шиндлера. Вони не є "чистим добром". Дійсно, коментарі - у кращому випадку, необхідне зло. Якби наші мови програмування були досить виразними або якщо ми мали талант тонко володіти цими мовами, щоб висловити свій намір, нам не дуже потрібні коментарі - можливо, зовсім не так.

Правильне використання коментарів - це компенсувати наше неспроможність висловити себе в коді. Зауважте, що я використав слово "провал". Я мав це на увазі. Коментарі завжди невдачі. Ми повинні їх мати, тому що ми не завжди можемо зрозуміти, як висловити себе без них, але їх використання не є причиною для святкування.

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

(Скопійовано звідси , але оригінальна цитата - з чистого коду: Довідник Agile Craftmanship Software )

Як ця цитата зводиться до "Коментарі - це завжди невдачі" - хороший приклад того, як деякі люди виймають розумну цитату з контексту і перетворюють її на дурну догму.


Документація API (на зразок javadoc) повинна документувати API, щоб користувач міг її використовувати без зчитування вихідного коду . Тож у цьому випадку документація повинна пояснювати, що робить метод. Тепер ви можете стверджувати, що "Вилучення продукту за його ідентифікатором" є зайвим, оскільки це вже вказано назвою методу, але інформацію, яка nullможе бути повернута, безумовно, важливо документувати, оскільки це жодним чином не очевидно.

Якщо ви хочете уникнути необхідності коментаря, вам слід усунути основну проблему (яка використовується nullяк дійсне значення повернення), зробивши API більш явним. Наприклад, ви можете повернути якийсь Option<Product>тип, тому сам підпис типу чітко повідомляє, що буде повернуто, якщо продукт не буде знайдено.

Але в будь-якому випадку не реально повністю документувати API лише через назви методів та підписи типів. Використовуйте doc-коментарі для будь-якої додаткової неочевидної інформації, яку повинен знати користувач. Скажімо, документація API з DateTime.AddMonths()BCL:

Метод AddMonths обчислює отриманий місяць та рік, враховуючи високосні роки та кількість днів у місяці, а потім коригує денну частину результуючого об'єкта DateTime. Якщо отриманий день не є дійсним днем ​​у отриманому місяці, використовується останній дійсний день місяця, що виходить. Наприклад, 31 березня + 1 місяць = 30 квітня. Часова частина доби результату об'єкта DateTime залишається такою ж, як і цей екземпляр.

Ви не можете висловити це за допомогою лише імені методу та підпису! Звичайно, ваша документація про клас може не вимагати такого рівня деталізації, це лише приклад.


Вбудовані коментарі теж непогані.

Погані коментарі - погані. Наприклад, коментарі, які пояснюють лише те, що можна побачити з коду, класичний приклад:

// increment x by one
x++;

Коментарі, які пояснюють те, що можна було б зрозуміти, перейменувавши змінну чи метод або іншим чином переструктурувавши код, - це запах коду:

// data1 is the collection of tasks which failed during execution
var data1 = getData1();

Це такі зауваження, проти яких Мартін реверує. Коментар є симптомом невдачі написати чіткий код - у цьому випадку використовувати назви змінних та методів, що роз'яснюються. Сам коментар, звичайно, не проблема, проблема полягає в тому, що нам потрібен коментар, щоб зрозуміти код.

Але коментарі слід використовувати для пояснення всього, що не очевидно з коду, наприклад, чому код написаний певним не очевидним способом:

// need to reset foo before calling bar due to a bug in the foo component.
foo.reset()
foo.bar();

Коментарі, які пояснюють, що надмірно заплутаний фрагмент коду - це також запах, але виправлення не в тому, щоб коментувати поза законом, виправлення - це виправити код! У реальному слові, зведений код трапляється (сподіваємось лише тимчасово, поки рефактор), але жоден звичайний розробник не пише ідеального чистого коду вперше. Коли відбувається заплутаний код, набагато краще написати коментар з поясненням того, що він робить, ніж не писати коментар. Цей коментар також спростить рефакторинг пізніше.

Іноді код неминуче складний. Це може бути складний алгоритм, або це може бути жертвою ясності з точки зору продуктивності. Знову ж необхідні коментарі.


13
Там також той випадок , коли ваш код обробляє ситуацію , яка просто є складним, і не простий код не може впоратися з цим.
gnasher729

6
Добрий момент, скрегіт. Це, здається, часто трапляється, коли вам доведеться оптимізувати деякий фрагмент коду для продуктивності.
ЖакБ

9
Навіть коментар x++може бути хорошим, якщо це щось на кшталт "збільшення х на один, обертання навколо, якщо це UINT32_MAX"; кожен, хто знає специфікацію мови, знав би, що приріст uint32_tзагортання загортається, але без коментаря може не знати, чи таке обгортання було очікуваною частиною впровадженого алгоритму.
supercat

5
@ l0b0: Сподіваюся, ти жартуєш!
ЖакБ

9
@ l0b0 Не існує такого поняття, як тимчасовий код. Код ніколи не буде відновлений, оскільки бізнес був задоволений результатом і не схвалив фінансування для його виправлення. Через п'ять років якийсь молодший розробник побачить цей код, ви навіть більше не використовуєте WizBug 4.0, оскільки ви замінили його на Bugtrocity v9, тому "Bug123" для нього нічого не означає. Він вважає, що саме таким повинен бути постійний код, і він продовжує бути жахливим розробником протягом усієї своєї кар'єри. Подумайте про дітей. Не пишіть тимчасовий код.
corsiKa

36

Існує різниця між коментуванням коду та документуванням коду .

  • Коментарі потрібні, щоб пізніше зберегти код, тобто змінити сам код.

    Коментарі дійсно можуть сприйматися як проблемні. Крайнім моментом буде сказати, що вони завжди вказують на проблему, або у вашому коді (код занадто важкий для розуміння), або в межах мови (мова не в змозі бути достатньо виразною; наприклад, факт, що метод ніколи не повертається, не nullможе бути виражений через контракти Code в C #, але немає можливості висловити це через код у, скажімо, PHP).

  • Документація необхідна для того, щоб мати можливість використовувати розроблені вами об'єкти (класи, інтерфейси). Цільова аудиторія різна: тут ми говоримо не про осіб, які підтримуватимуть ваш код і змінюватимуть його, а люди, які ледве потребують його використання .

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


Так, але, принаймні, частина думки Мартіна полягає в тому, що при сучасній практиці розробки тести - це документація, а не сам код. Якщо припустимо, що код тестується за допомогою тестової системи в стилі BDD, наприклад, specflow, самі тести є безпосередньо читабельним описом поведінки методу ("дається база даних продуктів, коли GetById викликається з ідентифікатором дійсного продукту" відповідний об’єкт Product повертається [...], коли GetById викликається з недійсним ідентифікатором продукту, тоді нуль повертається "або щось подібне).
Жуль

13

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

Ваш коментар щодо того, що робить функція, повинен бути таким, що ви можете викинути код реалізації, я прочитав коментар функції, і я можу написати заміну на реалізацію, не пішовши нічого поганого.

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

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

PS. Я бачив ваш рядок "іноді це частина інтерфейсу, тому ви навіть не знаєте, який код працює". Навіть лише з віртуальними функціями ви не знаєте, який код працює. Гірше, якщо ви написали абстрактний клас, навіть коду немає! Отже, якщо у вас є абстрактний клас з абстрактною функцією, коментарі, які ви додаєте до абстрактної функції, - це єдине, чим повинен керувати їх виконавець конкретного класу. Ці коментарі також можуть бути єдиним, що може керувати користувача класу, наприклад, якщо у вас є абстрактний клас та фабрика, що повертає конкретну реалізацію, але ви ніколи не бачите жодного вихідного коду реалізації. (І звичайно, я не повинен дивитися на вихідний код однієї реалізації).


Я не коментував код за 10 років. Відгуки - здуття, сміття. Ніхто не коментує код в ці дні. Ми зосереджуємось на добре сформованому та названому коді, невеликих модулях, роз'єднанні і т. Д. Це робить ваш код читабельним, а не коментарі. Тести гарантують, що якщо ви викинете код, нічого не піде не так, не коментарі. Тести показують, як ви використовуєте написаний код, як ви їх називаєте і чому вони там в першу чергу. Ви занадто стара школа, вам потрібно вивчати тестування та чистити код мого друга.
PositiveGuy

12

Можна розглянути два типи коментарів - ті, які видно людям з кодом, і такі, які використовуються для створення документації.

Тип коментаря, на який дякує дядько Боб, - такий вид, який видно лише людям з кодом. Що він обстоює - це форма СУХОГО . Для людини, яка переглядає вихідний код, вихідним кодом має бути документація, яка їм потрібна. Навіть у випадку, коли люди мають доступ до вихідного коду, коментарі не завжди є поганими. Іноді алгоритми складні або вам потрібно зафіксувати, чому ви користуєтеся неочевидним підходом, щоб інші не закінчилися порушувати ваш код, якщо вони намагаються виправити помилку або додати нову функцію.

Описані вами коментарі - це документація API. Це речі, які видно людям, які використовують вашу реалізацію, але можуть не мати доступу до вихідного коду. Навіть якщо вони мають доступ до вашого вихідного коду, вони можуть працювати над іншими модулями і не дивляться на ваш вихідний код. Цим людям буде корисно мати цю документацію у своєму IDE під час написання коду.


Я, чесно кажучи, ніколи не замислювався про те, що DRY застосовується до коду + коментарів, але це має ідеальний сенс. На зразок подібного прикладу "збільшення X" у відповіді @ JacquesB.

7

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

/// <summary>
/// Retrieves a product by its id, returns null if no product was found.
/// </summary>

щодо вартості та вартості ми бачимо три речі:

  1. Retrieves a product by its idповторює те, що говорить назва функції, тому вона коштує без значення. Його слід видалити.

  2. returns null if no product was foundє дуже цінною інформацією. Це, швидше за все, скорочує час, коли інші кодери повинні будуть дивитись на реалізацію функції. Я впевнений, що це економить більше читання, ніж вартість читання, яку він представляє. Це повинно залишитися.

  3. Лінії

    /// <summary>
    /// </summary>
    

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

    З цієї причини використання генераторів документації є суперечливою ідеєю: вони, як правило, вимагають багато додаткових коментарів, які не містять інформації або повторюють очевидні речі, просто заради відшліфованого документа.


Спостереження, яке я не знайшов ні в одній з інших відповідей:

Навіть коментарі, які не потрібні для розуміння / використання коду, можуть бути дуже цінними. Ось один із таких прикладів:

//XXX: The obvious way to do this would have been ...
//     However, since we need this functionality primarily for ...
//     doing this the non-obvious way of ...
//     gives us the advantage of ...

Можливо, багато тексту, абсолютно непотрібного для розуміння / використання коду. Однак це пояснює причину, чому код виглядає так, як він є. Він зупинить людей, котрі не дивляться на код, дивуються, чому це не зроблено очевидним чином, і розпочнуть рефакторинг коду, поки вони не зрозуміють, чому код написаний таким чином в першу чергу. І навіть якщо читач достатньо розумний, щоб не переходити до рефакторингу безпосередньо, їм все-таки потрібно з’ясувати, чому код виглядає так, як це робиться, перш ніж вони зрозуміють, що він повинен залишатися таким, яким він є. Цей коментар може буквально заощадити години роботи. Таким чином, вартість вище, ніж вартість.

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


2
Вау - змінити генератор документів, тому що для розбору потрібна пара додаткових рядків HTML? Не будемо.
corsiKa

2
@corsiKa YMMV, але я б вважав за краще генератор документації, що зводить витрати на коментарі до мінімуму. Звичайно, я б краще прочитав добре написаний файл заголовка, ніж документацію доксигену, яка не синхронізована з фактичним кодом. Але, як я вже сказав, YMMV.
cmaster

4
Навіть якщо назва методу блискуче описує його мету, повторення цієї мети за допомогою природної мови може полегшити тому, хто її читає, пов'язувати цю мету з будь-якими застереженнями, що слідують за нею. Перегляд того, що описано в імені, буде досить коротким, що навіть якщо значення низьке, вартість також буде низькою. Тому я не погоджуюся з першою частиною вашої публікації. +1, однак, для другої частини. Документація альтернативних підходів, які були оцінені та відхилені, може бути надзвичайно цінною, але така інформація рідко приділяється увазі, яку вона заслуговує.
supercat

GetByIdставить питання, що ідентифікатор, а також, що звідки дістати. Коментар до документації повинен дозволяти середовищу розробки відображати відповіді на ці питання. Якщо це не пояснено деінде в коментарях модуля doc, це було б також одним місцем, де можна сказати, чому ви все одно отримаєте ідентифікатор.
Гайд

Відмітка щодо коментарів, чистий код (самоопис), TDD (часто отримуйте зворотний зв'язок і часто отримуєте відгуки про ваш дизайн), а також правила тестування (надайте вам впевненості та поведінки документів)! ТЕСТИ люди ТЕСТИ. Ніхто тут не говорить про це. прокидайтеся
PositiveGuy

4

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

Роберт Мартін та ін. вважайте це "неприємним запахом", оскільки можливо, що код змінено, а коментарі - ні. Я кажу, що це добре (точно так само, як до побутового газу додається "неприємний запах", щоб сповістити користувача про текти). Читання коментарів дає вам корисну вихідну точку тлумачення фактичного коду. Якщо вони збігаються, то у вас буде підвищена впевненість у коді. Якщо вони відрізняються, то ви виявили попереджуючий запах і потребуєте подальшого дослідження. Ліки від «неприємного запаху» полягає не в тому, щоб усунути запах, а ущільнити витік.


2
З огляду на те, що ви інтелігентний автор, і текст - на користь інтелектуальної аудиторії; Ви малюєте лінію, використовуючи здоровий глузд. Очевидно, як це нині, приклад є німим, але це не означає, що може бути не надто вагомий привід уточнити за допомогою коментаря, чому код містить i ++ у цій точці.
Вінс О'Салліван

8
i++; // Adjust for leap years.
Вінс О'Салліван

5
"Роберт Мартін та ін. Вважають це" неприємним запахом ", оскільки може статися так, що код змінено, а коментарі - ні". Це лише частина запаху. Найгірший запах походить від ідеї, що програміст вирішив не намагатися писати код більш описовим способом, а натомість вирішив «запечатати витік» коментарем. Його твердження полягає в тому, що замість удару коментаря "// коригування для високосних років", мабуть, у самому коді (або щось подібне) слід мати метод "prilagodForLeapYears ()". Документація надходить у вигляді тестів, що здійснюють логіку високосного року.
Ерік Кінг

3
Я б розглядав можливість додавання виклику методу для заміни одного рядка коду надлишком коментаря, тим більше, що назва методу насправді є лише коментарем, який мітить фрагмент коду і не гарантує кращої точності документації. (Якщо ця лінія відбуватиметься в двох чи більше місцях, то, звичайно, введення виклику методу було б, безумовно, правильним рішенням.)
Vince O'Sullivan

1
@Jay Причина полягає в тому, що правити чіткі абстракції (наприклад, вводячи методи) - це правило. Якщо цього не зробити, тому що ви можете отримати метод, у якого є один рядок, є виключенням. Дозвольте перефразовувати реальне довільне правило: "Використовуйте структури мови програмування (як правило, методи та класи) для введення абстракцій, якщо реалізація цієї абстракції не може бути виражена як один рядок коду; у цьому випадку вкажіть абстракцію природною мовою шляхом додавання коментар ".
Ерік

3

У деяких мовах (наприклад, F #) весь цей коментар / документація може бути фактично виражений у підписі методу. Це тому, що в F # нуль, як правило, не є дозволеним значенням, якщо спеціально не дозволено.

Що є загальним у F # (а також у кількох інших функціональних мовах), це те, що замість null ви використовуєте тип параметра, Option<T>який може бути Noneабо Some(T). Тоді ця мова зрозуміє це і змусить вас (або попередити, якщо ви цього не зробите) у обох випадках, коли ви намагаєтесь ним скористатися.

Так, наприклад, у F # ви могли мати підпис, який виглядає приблизно так

val GetProductById: int -> Option<Product>

І тоді це буде функція, яка приймає один параметр (int), а потім або повертає продукт, або значення None.

І тоді ви могли б використовувати це так

let product = GetProduct 42
match product with
| None -> printfn "No product found!"
| Some p -> DoThingWithProduct p

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

Звичайно, це вимагає, щоб ваша мова була розроблена таким чином - чого багато поширених мов, таких як C #, Java, C ++ тощо. Тож це може не допомогти вам у вашій нинішній ситуації. Але, сподіваємось, приємно знати, що там існують мови, які дозволяють висловлювати подібну інформацію статично введеним способом, не вдаючись до коментарів тощо. :)


1

Тут є кілька відмінних відповідей, і я не хочу повторювати те, що вони говорять. Але дозвольте додати кілька коментарів. (Каламбур не призначений.)

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

Ідея, що код повинен бути самодокументованою, є однією з таких відмінних ідей. Але в реальному житті існують обмеження щодо практичності цієї ідеї.

Одним із зауважень є те, що мова може не містити функцій для документального підтвердження того, що потрібно чітко та стисло зафіксувати. У міру вдосконалення комп'ютерних мов це стає все менше і менше. Але я не думаю, що це повністю пішло. Ще в ті часи, коли я писав у асемблері, було багато сенсу включати коментар на кшталт "загальна ціна = ціна неоподатковуваних предметів плюс ціна предметів, що оподатковуються, плюс ціна оподатковуваних предметів * ставка податку". Те, що було в реєстрі в будь-який момент, не завжди було очевидним. Потрібно було багато кроків, щоб зробити просту операцію. І т. Д. Але якщо ви пишете сучасною мовою, такий коментар був би просто перерахуванням одного рядка коду.

Мене завжди дратує, коли бачу коментарі на кшталт "x = x + 7; // додати 7 до x". Мовляв, вау, дякую, якби я забув, що означає знак плюс, який, можливо, був би дуже корисним. Де я можу насправді заплутатися - це знати, що таке «х» або чому потрібно було додати 7 до нього саме в цей час. Цей код можна зробити самодокументованим, давши більш значущу назву "x" та використовуючи символічну константу замість 7. Як і коли б ви написали "total_price = total_price + MEMBERSHIP_FEE;", то коментар, ймовірно, зовсім не потрібен. .

Чудово звучить, що ім’я функції повинно точно говорити, що функція робить, щоб будь-які додаткові коментарі були зайвими. У мене є приємні спогади про час, коли я писав функцію, яка перевіряла, чи є номер елемента в нашій таблиці баз даних, повертається як істинне чи помилкове, і яке я назвав "ValidateItemNumber". Здавалося, гідне ім’я. Потім хтось інший прийшов і змінив цю функцію, щоб також створити замовлення для елемента та оновити базу даних, але ніколи не змінював назву. Тепер назва була дуже оманливою. Це звучало так, ніби це зробило одне невелике, коли насправді це зробило набагато більше. Пізніше хтось навіть взяв частину про підтвердження номера товару і зробив це десь в іншому місці, але все ж не змінив назву. Тож хоча функція тепер не мала нічого спільного з валідацією номерів елементів,

Але на практиці часто неможливо, щоб ім'я функції повністю описало, що функція робить, а не ім'я функції до тих пір, як код, який складає цю функцію. Чи буде ім'я точно говорити нам, які перевірки виконуються за всіма параметрами? Що відбувається на умовах виключення? Вияснити всі можливі неясності? У якийсь момент назва набуде такої тривалості, що вона просто стає заплутаною. Я б прийняв String BuildFullName (ім'я рядка, прізвище рядка) як гідний підпис функції. Навіть незважаючи на те, що ім'я виражається "перший останній" або "останній, перший" чи якась інша зміна, що робити, якщо одна або обидві частини імені порожні, якщо вони встановлюють обмеження на комбіновану довжину та що він робить, якщо це перевищено,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.