Як я можу визначити та виміряти простоту в коді?


13

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

Як я можу визначити простоту в коді? Які програмні вимірювання та показники доступні для вимірювання простоти коду?


2
@MarkTrapp Є й інші способи обговорення простоти коду без тем з емпіричної інженерії програмного забезпечення, теми, які я набагато менш знайомий. Наприклад, обговорення простоти з точки зору можливості писати автоматизовані тести. Мої навички та знання дозволяють мені відповісти на це питання з погляду емпіричного програмного інженера, тоді як інші можуть відповісти з альтернативних точок зору. Додавання цього запитання до питання значно обмежує кількість корисних відповідей, що робить його (ІМО) занадто локалізованим. Якщо ви хочете додати його, ви можете, але це хороше питання як є.
Томас Оуенс

2
@ThomasOwens На справжні запитання є відповіді , а не ідеї чи думки. Звуження сфери дії, тому всі трактують, як відповісти на питання однаково, саме те, що стосується Stack Exchange. Можливо, існує декілька підходів до вирішення проблеми, але існує лише одна однозначно викладена проблема.

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

@MarkTrapp Проблема однозначна: як визначити простоту коду? Є кілька хороших відповідей. Шахта - це використання емпіричних методів інженерії програмного забезпечення для вимірювання складності. Іншим може бути написання автоматизованих тестів, і якщо складно написати хороші тести, код складний - цілком коректна відповідь. Можуть бути й інші, про які я не знаю. Якщо вам потрібно виміряти складність / простоту бази коду, питання слід сформулювати таким чином, щоб представити всі альтернативи, щоб запитувач міг вибрати найкраще рішення для свого конкретного випадку.
Томас Оуенс

Відповіді:


16

Найпоширенішими показниками для вимірювання складності (або простоти, якщо ви вважаєте, що простота є протилежною складності) - це цикломатична складність МакКейба і метрика складності Халстеда .

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

Заходи складності Галстеда використовують входи загальних та окремих операторів та операндів для обчислення обсягу, складності та зусилля фрагмента коду. Складність, яка полягає в (кількість унікальних операторів / 2) * (загальна кількість операндів / кількість унікальних операндів), пов'язана з можливістю читання та розуміння коду для таких завдань, як вивчення системи або проведення перевірки коду. Знову ж таки, ви можете порахувати це на системному рівні, рівні класу або на рівні методу / функції. Існує кілька публікацій про обчислення цих вимірювань тут і тут .

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

Fan-in і fan-out - це дві інші показники, пов’язані з потоком даних. Як визначено тут , вентилятор - це сума викликів процедур, зчитуються параметри, а глобальні змінні, що читаються та вивіряються - це сума процедур, які викликають певну процедуру, параметри, записані (піддаються стороннім користувачам, передаються посиланням), і глобальні змінні, записані в. Знову ж таки, високий вентилятор і вентилятор можуть бути свідченням модуля, який може бути важко зрозуміти.

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

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


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

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

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

7

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

Я не вкладаю міри простоти, але коли ви називаєте щось просте чи ні.

1. Перехід коду:
Наскільки легко переміщатися по коду? Чи легко визначити, де записані функції API? Чи легко зрозуміти потоки викликів, наприклад, які методи викликають інших (і чому) - чи реалізовані хороші стан машини чи чітко визначені алгоритми?

Коли проїзд коду простий, його легко дотримуватися.

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

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

4. Залежність або з'єднання
Це важко судити, лише переглядаючи код, але стає дуже очевидним, якщо хтось намагається виправити ваші помилки. Коли в іншому об'єкті змінюються інші речі , чи змінюється тут операція? Ці зміни очевидні? Чи потрібно вам так часто змінювати API, щоб вмістити речі. Вони говорять про те, що міжмодульні відносини не є простими

5. Вхідні дані користувача або програми
Нарешті, наскільки просто вводяться користувацькі вклади або програми в API / інтерфейс користувача? Коли вам потрібно дати декілька можливих користувачів / додатків (для різних цілей) - вони очевидні? Чи існують стани / деталі, які не пов'язані з вищою абстракцією, але все-таки повертаються назад-п-назад інтерфейс?

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

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


1
Він попросив вимірювання та показники. Вони є суб'єктивними, тому я не думаю, що вони дуже налаштовані.
psr

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

"використовувати імена, які неможливо зрозуміти неправильно" - ІМХО це націлений занадто високо, до нереалістичної та неможливої ​​мети. Я б не намагався бути настільки визначеним і просто сказав "використовувати чіткі та однозначні імена".
Péter Török

@ PéterTörök Я згоден. Я думаю, що зазвичай у багатьох організаціях зберігаються дуже чітко визначені правила іменування конвенцій, і все ще існує деяка плутанина щодо наміру конкретної змінної. Отже, наголос повинен був сказати, що ясність мети означає простоту, а не формальне правило. Можливо, я перебрався за борт у тому, як я описав. Спасибі.
Діпан Мехта

@Dipan Цикломатична складність пов'язана з читабельністю коду за допомогою робочої пам'яті. Код з високою цикломатичною складністю (або навіть просто великою глибиною блоку) важко зберігати в робочій пам'яті, тому складніше читати прямо.
Томас Оуенс

0

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

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

  • Простота конструкцій в межах програми: Ви можете виміряти кількість параметрів, яку приймає функція. Якщо у вас є> n % усіх функцій з параметрами > m , ви можете вважати, що це вважається не простим, залежно від того, як ви визначаєте n і m (можливо, n = 3 і m = 6?). Я думаю, що є кілька інструментів статичного аналізу, які можуть вимірювати це - я думаю, що JTest просто виміряв функції з параметрами > m .

  • Ви можете спробувати підрахувати кількість вкладених циклів або структур управління. Це, на мою думку, насправді не є поганою метрикою, і я думаю, що це назва (не можу згадати вгорі голови). Знову ж таки, я думаю, що є інструменти (знову ж таки, як JTest), які можуть міряти це, до певної міри.

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

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


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

Немає жодного пояснення?
FrustratedWithFormsDesigner

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

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

@ SK-логіка: я думаю, я мав би назвати цю "розумність", це ближче до того, що я мав на увазі. Я б лише сказав, що подібні речі ?:є проблемою, коли вони вкладені 5 глибоко. Що стосується шарів, то чисто розділені шари краще, ніж один згорнутий шар. Але 7 здебільшого зайвих шарів, коли потрібно було лише 2 або 3 - це погано.
FrustratedWithFormsDesigner
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.