Чому використання сполучників у назвах методів є поганою умовою іменування? [зачинено]


12

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

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

Нещодавно вони запропонували щось, що мені здається дуже дивним: усі методи повинні мати сполучники у своєму імені, наприклад getEntityOrNull, setValueOrExceptionтощо.

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

Єдине, що я придумав:

  • така інформація повинна бути присутня в анотаціях методу, як @returnабо@throws
  • використання сполучників ("і", "або" тощо) у назвах методів зазвичай говорить про те, що Принцип єдиної відповідальності належним чином не дотримується

Які ще є конкретні аргументи проти цієї конвенції про іменування?


як правило, ви не можете
gnat

5
the use of conjunctions ("and", "or" etc.) in method names usually suggest that the Single Responsibility Principle is not properly respectedЦе не стосується наведених вами прикладів, де сполучник використовується для уточнення механізму, що використовується для обробки несправностей, а не для вказівки, що це може зробити те чи інше. Навіть найбільш вузько визначена функція може мати законні умови відмови, наприклад, вискакування порожнього стека.
Довал

4
Розглянемо: (1) використання "необов'язкового", а не "або нульового". "GetOtionalEntity" звучить краще на моє вухо, ніж "GetEntityOrNull". (2) бібліотека базового класу .NET використовує умову, що якщо у вас є два методи, які відрізняються лише тим, що вони кидають, назвіть той, який не може кинути "TryBlah". Наприклад, Int32.TryParseі Int32.Parse- обидва розбирають рядок на ціле число, але перший повертає булеве значення, що вказує на успіх, а друге кидає на провал.
Ерік Ліпперт

Я б не використовував суфікс для варіанту метання, але я би використав його для нульового варіанту повернення. Може бути Try..., ...OrNull, ...OrDefault. @EricLippert Це не єдина конвенція в .net. Поміркуйте Singleпроти SingleOrDefault, що дуже близьке до OrNullзапропонованої ОП.
CodesInChaos

Відповіді:


11

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

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

Іншими словами, якщо getValueOrNullвиклик є просто викликом getValueOrException, фіксуючи виняток, і в цьому випадку повертається null, це може здійснити абонент. Це захаращує клас методами, які насправді не сприяють нічого корисного. Швидше я віддаю перевагу getValue, і знаю, що це кидає виняток. Ще краще, я хотів би знати, що всі методи отримують винятки, і жоден з них не повертається, nullщоб поведінка була рівномірною протягом усього мого проекту, або, навпаки, всі потенційно поверталися null, і знаю, що абоненту доведеться кинути виняток, якщо які були бажані.

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


Якщо вам довелося вибрати лише одну, краще повернутись null(або ще краще, необов’язково / тип), оскільки метання відносно дороге. Написання помічника, який перевіряє, чи значення недійсне та кидає, не додає великих витрат. Однак, коли ви хочете версії без кидка, проковтування винятку не поверне вам удар, коли ви його кинули.
Довал

1
@Doval Добре, і, що може бути важливіше, винятки повинні бути винятковими . Якщо ви часто кидаєте винятки, ви не використовуєте їх правильно. Єдиною проблемою з поверненням nullє те, що nullнасправді може бути дійсним поверненням у деяких випадках, тож вам доведеться відхилитися від норми і кинути виняток у таких випадках.
Ніл

3

Хоча використання сполучників часто вказує на порушення SRP, у цьому випадку це лише вказівка ​​на повернене значення алгебраїчного типу бідної людини, яке може бути одним із двох значень, або значенням null"успіху".

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

Крім того, я вважаю, що @throwsанотації не є обов'язковими для php, тому відсутність анотації не вказує на відсутність винятку, хоча це краще вирішити, зробивши примітку обов’язковою у вашому посібнику зі стилів.

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


2

У своєму коді я колись створюю пари методів з іменами, такими як getEntity () та getEntityOrNull (). Назва пояснює очікувану поведінку. Якщо getEntity () не знаходить сутності, викидається виняток. getEntityOrNull () поверне нуль.

Роблячи це, код виклику стає дещо чіткішим. Якщо викликовий код повинен мати сутність, то getEntity зробить свою справу. Якщо сутність є якимось необов'язковим thingee, то getEntityOrNull є методом вибору.

Те ж саме можна зробити одним методом, але це перекладає частину тягаря на програму, що викликає. Вам завжди потрібно перевірити наявність нуля або вам потрібен блок "try / catch". У будь-якому випадку це додатковий код, який потрібно дублювати щоразу, коли метод викликається.

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

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

Ви можете розглянути питання архітекторів, чому. Ті, кого я знаю, завжди раді пояснити свої рішення. Часто у великих (а іноді і мучних) деталях.


Те, що getEntity викине виняток у випадку невдачі, мені зовсім не зрозуміло, я б очікував простої NULL.
Elise van Looij

1

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

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

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