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


25

Чи справді хороший принцип стилю кодування - наприклад, принцип єдиного виходу? Завжди чи просто іноді? Скільки різниці це насправді?

Якою б не була ваша думка, це, очевидно, суб'єктивні питання. Або вони?

Хто-небудь намагався зробити об'єктивне, науково суворе дослідження принципів стилю кодування?

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


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

Це також сильно залежить від мови, деякі принципи застосовуються до конкретних мов, а не до інших. Наприклад, це single-exit principleдійсно не стосується C ++ через RAII
Мартін Йорк


@Loki - мені довелося подумати над цим, і я не впевнений, що згоден. Це правда, що RAII розроблений значною мірою для вирішення винятків, які є альтернативними точками виходу, але (принаймні для деяких людей) вони розглядаються як альтернативні альтернативні точки виходу - насправді не рахуються проти принципу єдиного виходу таким чином break, gotoабо returnробити. Один вихід IOW не є абсолютним для C ++, але це, як я бачу, на мові C та більшості інших мов. Але це все-таки актуально в не строгому сенсі.
Steve314

1
@ Steve314, стаття є принаймні віддаленою - вона окреслює проект методології такого експерименту, що досить важливо через очевидну відсутність належним чином записаних експериментальних доказів у цій галузі.
SK-логіка

Відповіді:


11

Я повторюю коментар deadalnix: прочитайте Code Complete 2 . Автор (Стів Макконнелл) глибоко обговорює стиль кодування та часто посилається на документи та дані.


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

Я не читав цю книгу, і, можливо, мав би бути, але - виходячи з коментарів у гнаті відповіді - чи справді документи, на які посилаються, дійсно науково суворі та об'єктивні? Якщо відповідь «стільки, скільки вони можуть бути», які компроміси були необхідні? Як я запропонував у питанні, чи потрібно було замінити подвійний штор на якийсь слабший стандарт?
Steve314

@ Steve314: Я не знаю, я не перевіряв джерела! Але вам не завжди потрібна наукова суворість для встановлення найкращої практики. Іноді достатньо обговорення плюсів і мінусів.
М. Дадлі

@emddudley - абсолютно правда, але насправді не про це питання.
Steve314

@ Steve314: Code Complete був би чудовою відправною точкою для вас, і я впевнений, що деякі його посилання стосуються питання наукового аналізу стилю кодування.
М. Дадлі

12

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

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

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

Але вдосконалені альтернативи, такі як Дворак або Колемак, ніколи не натрапляли і навряд чи будуть. І тому люди не більш продуктивні з ними - факт. Навіть якщо вони вищі в якомусь абстрактному сенсі.

Крім того, важко буде знайти суб'єктів, які не мали попереднього впливу на програмування (оскільки це забруднило б результат нашого дослідження), АЛЕ здатність до програмування, І бажання брати участь у дослідженні протягом досить тривалого періоду, щоб показати як короткий -часні вигоди та тривалі вигоди, щоб їх можна було порівняти з іншими ... (не знаю, чи взаємно виключаються вони, але дослідники не могли просто припустити, що вони ніколи не є).


1
Класно, я ніколи раніше не чув про
Колемак

1
@Chad ще менш відомим є Carpal X, з яким я грав на деякий час. Я вважав його приємнішим за Колемака (я досягав 90-100 об / хв за допомогою карпалсу). Навіть якщо ви не маєте наміру переходити до будь-яких екзотичних макетів, веб-сайт carpalx робить надзвичайно цікавим питання про оцінку та оптимізацію розкладки клавіатури та використання генетичних алгоритмів для цієї категорії проблем. Дивіться mkweb.bcgsc.ca/carpalx
Конрад Моравський

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

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

1
@ Джеремі Суть цих витрат на усиновлення полягає в тому, що люди краще працюють із неповноцінним інструментом до тих пір, поки у них було більше практики. І саме це виявиться в будь-якому дослідженні, що намагається дослідити, наскільки добре його суб'єкти справляються з різними стилями кодування. Шум, спричинений їх попереднім знайомством / незнайомістю стилів кодування, якими ви користуєтесь би, зменшив вплив будь-яких природжених якостей цих стилів. Якщо ви не вирівняли ігровий майданчик, взявши за собою початківців. Але це становить практичні труднощі, на що я вказував в останньому абзаці своєї відповіді.
Конрад Моравський

4

Відповідь - остаточний НІ! Чи погані практики програмування "перерва" та "продовження"? це підмножина цього питання, тож я розпочну з ледь зміненої відповіді на це ...

Ви можете [повторно] писати програми без заяв про перерви (або повернення з середини циклів, які роблять те саме). Але при цьому вам може знадобитися ввести додаткові змінні та / або дублювання коду, обидві з яких, як правило, ускладнюють розуміння програми. Паскаль (мова програмування кінця 1960-х) був дуже поганим, особливо для початківців програмістів з цієї причини.

Є результат інформатики, який називається ієрархією структур управління Косараджу, яка починається з 1973 року і про яку згадується у відомому документі " Структуроване програмування Кнута", що переходить до тверджень 1974 року. Те, що довів С. Рао Косараджу в 1973 році, це те, що це не так можна переписати всі програми, які мають багаторівневі перерви глибини n в програми з глибиною розриву менше n без введення зайвих змінних. Але скажімо, що це лише суто теоретичний результат. (Просто додайте кілька додаткових змінних ?! Напевно, ви можете зробити це, щоб відчути, що група з 3K + користувачами в stackexchange ...)

Що набагато важливіше з точки зору інженерії програмного забезпечення - це нещодавніший документ Еріка С. Робертса 1995 року під назвою " Вихід з циклу та структуроване програмування: повторне відкриття дискусії" (дой: 10.1145 / 199688.199815). Робертс підсумовує кілька емпіричних досліджень, проведених іншими перед ним. Наприклад, коли групі студентів типу CS101 було запропоновано написати код функції, що реалізує послідовний пошук у масиві, автор дослідження сказав наступне про тих студентів, які використовували перерву / повернення для виходу з послідовного цикл пошуку праворуч, коли елемент був знайдений:

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

Робертс також говорить, що:

Студенти, які намагалися вирішити проблему, не використовуючи явного повернення з циклу for for, пройшли набагато менше: лише семеро з 42 студентів, які намагалися використовувати цю стратегію, змогли створити правильні рішення. Цей показник представляє рівень успішності менше 20%.

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

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

Отже, в основному кожен, хто заперечував вище про те, що принцип сингє-виходу досі корисний сьогодні, також сперечається проти парадигми обробки винятків, якщо не використовується вкрай обмежуючим способом, описаним у цьому останньому посиланні; ці вказівки в основному обмежують всі винятки з функції передачі (), тобто поширення виключень між функціями взагалі не дозволено. Насолоджуйтесь своїм новим Pascal за допомогою синтаксису, подібного до C ++.

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


Я не спростовував цього, але щодо вашого "Але, можливо, вам доведеться ввести додаткові змінні та / або дублювання коду, обидві з яких, як правило, ускладнюють розуміння програми". пункт, це суб'єктивна претензія. Я погоджуюся, що додавання змінної чи кодування дублює труднощі, але, мабуть, додавання goto також важко зрозуміти, плюс, мабуть, шкода, завдана шляхом дублювання, може бути зменшена шляхом фактурирования дублюючого коду у функцію (хоча IMO рухається складність у графіку виклику не усуває його автоматично).
Steve314

Я побачив вашу думку про папір 1995 р. Лише після останнього коментаря, і вирішив підкреслити - цікавий момент. Я думаю, що ваш голос може бути більше, тому що ваш пост довгий і починається з суб'єктивного моменту, тому, мабуть, першокласник не прочитав все це (так само, як я, спочатку). В основному, це гарна ідея представити свою справжню точку рано.
Steve314

У будь-якому випадку, я думаю, що багато людей вважають винятки як різновид альтернативних альтернативних точок виходу - тому що вони призначені для випадків помилок (свого роду), вони насправді не рахуються. Я розумію, що це трохи чутливо до мовної культури. У деяких мовах "виняток" більше, ніж назва - винятковий випадок успіху є дійсним (і IIRC Stroustrup сказав щось подібне про C ++, піднімаючи філософський пункт про те, чи помилка є помилкою, якщо її обробляють). Деякі навіть кажуть, що винятки - це ще один контрольний потік, який потрібно використовувати, коли він дає необхідний контрольний потік.
Steve314

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

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

1

http://dl.acm.org/citation.cfm?id=1241526

http://www.springerlink.com/content/n82qpt83n8735l7t/

http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=661092

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


1
@ luis.espinal: До якого кінця? Яку інформацію містив би текст? Питання обводиться трохи. Яку частину питання слід вирішити з деяким текстом?
S.Lott

1
Що стосується стилю та, можливо, для того, щоб надати більше інформації, яку можуть навести реферати посилань (враховуючи, що ми не знаємо, чи є ОП платним членом ACM / IEEE / Springer Verlag з доступом до повних статей та знайти відповіді на Наприклад, у рефераті статті ACM не згадується стиль кодування. Щонайбільше йдеться про підтвердження теореми структурованої програми (яка сама по собі не говорить про єдину чи множинну проблему повернення). Тож ви могли пояснити, чому це посилання є релевантним.
luis.espinal

1
Третя стаття (на щастя, я маю доступ до IEEE Xplore), схоже, не пов'язана з тим, що просить ОП, наскільки я можу сказати. Це чудова стаття, пам’ятайте, яку я друкую для більш присвяченого читання пізніше. Тож, можливо, ви могли б також пояснити, як ця стаття допомагає ОП відповісти на його запитання. Загалом, здається, ви просто зв'язали купу зв’язків. Це не спосіб зневаги (якщо це не був ваш намір), але, знову ж таки, я не розумію, як це допомогло ОП. І саме тому плакат повинен додати текст за своїми посиланнями. Тож тепер ви знаєте, чому я це сказав;)
luis.espinal

1
з вуст ОП Is a coding style principle - e.g. the single-exit principle - really a good thing?- це дає контекст питанню, яке він ставить, про стилі кодування. Крім того, стиль кодування не є таким самим, як методологія програмування, зокрема методи проектування високого рівня, які є в центрі уваги статті IEEE (чітко зазначено авторами.) Тому я кажу "ні" - сфери застосування абсолютно різні.
luis.espinal

1
Я підозрюю, звідки береться ОП. Він чітко визначає стилі кодування (а не методології), і, зокрема, одиночне проти множинного повернення. Мені довелося впоратися з цим пару разів з добре написаним, по суті, самоочевидним кодом, використовуючи кілька заявок повернення, переписуючи їх у більш складні версії, використовуючи одноразове повернення (зокрема, у великих організаціях, що мають велику кількість червоних стрічок) * як за "процес". І дивується (і кидає виклик доказів) обгрунтованість, зручність використання та економічність таких довільних мандатів. Люди, які змушують такі мандати, досі живуть у 60-х роках: /
luis.espinal

1

Це принцип стилю кодування - наприклад, принцип єдиного виходу

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

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

Щодо решти моїх відповідей, то це все відносно (що не в програмному забезпеченні?):

  • дійсно гарна річ?

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

Завжди чи просто іноді?

Більшість часу.

Скільки різниці це насправді?

Залежить.

Читаний код проти нечитабельного коду. Підвищена складність (про яку ми повинні знати на сьогоднішній день збільшує ймовірність введення помилок) проти більш простої складності (і ерго, менша ймовірність помилок.) Мови, компілятори яких не додають неявного повернення (скажімо, Pascal, Java або C #), і ті, які за замовчуванням до int (C і C ++).

Зрештою, це вміння, відточене у людини / години за клавіатурою. Іноді нормально мати кілька повернених висловлювань, як тут (у деяких псевдокодах Pascal'esque):

function foo() : someType
  begin
  if( test1 == true )
  then
    return x;
  end
  doSomethignElseThatShouldnHappenIfTest1IsTrue();
  return somethingElse();
end;

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

Іноді це не так (тут використовується псевдокод, подібний С):

switch(someVal)
{
case v1 : return x1;
case v2 : return x2:
case v3 : doSomething(); // fall-through
case v4: // fall-through
case v5: // fall-through
case v6: return someXthingie;
...
...
default:
   doSomething(); // no return statement yet
}

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

Можливо, алгоритм правильний, але погано написаний.

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

Можливо, це неправильно.

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

Припускаючи фрагмент коду, який вважається правильним:

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

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

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

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

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

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

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

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

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


1
Тип повернення C ++ не є типовим для int: тип повернення за замовчуванням не існує, тому він повинен бути вказаний у всіх випадках.
Sjoerd

З перш ніж я писав це питання - programmers.stackexchange.com/questions/58237 / ... . В основному я виступаю за усвідомлення принципу, але не суворо його дотримуюся - якщо всі точки виходу очевидні, я задоволений. Моя думка тут - тільки те, що я згадую принцип як приклад, не означає, що я виступаю за цей принцип, і, звичайно, не в його суворій формі. Моя суб'єктивна думка - це саме те - можливо, є більш сильний аргумент на мій погляд, а може бути, є сильний аргумент, що я помиляюся.
Steve314

Що таке "за замовчуванням для int"?
curiousguy

Я маю на увазі сказати, і я мав би це кваліфікувати, що більшість компіляторів просто "засунуть" значення реєстру акумулятора як повернене значення, якщо в коді є гілка виконання без явного значення повернення. Це фактично означає повернення результату останньої арифметичної операції (будь-якого сміття, що може бути) у формі int. І це, звичайно, сміття (і ерго, невизначена поведінка) незалежно від того, яку функцію планували виконувати в першу чергу. C і C ++ можуть попередити вас, але компіляція дозволить вам компілювати, якщо ви не використовуєте -Werror або щось подібне.
luis.espinal
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.