Читабельність

Зміст

Читабельність#

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

Правопис#

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

Використання підкреслень#

настанова#

  • Використовуйте підкреслення, щоб відокремити слова у складній назві.

приклад#

Милі_за_годину
Вхідна_вартість

обгрунтування#

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

Числа#

настанова#

  • Послідовно зображуйте числа.

  • Представляти літерали у радіксі, що відповідає задачі.

  • Використовуйте підкреслення для розділення цифр так само, як у звичайному тексті використовуються коми або крапки (або пробіли для не десяткових основ).

  • Використовуючи наукову термінологію, послідовно пишіть "Е" або з великої, або з малої літери.

  • В альтернативній системі числення подайте літери або всіма великими, або всіма малими літерами.

конкретизація#

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

  • У наукових позначеннях "Е" завжди пишеться з великої літери.

  • Використовуйте великі літери для позначення цифр у системах числення з основою понад 10.

  • Шістнадцяткові числа згруповані по чотири, починаючи з обох боків від точки радіксу.

приклад#

#include x1

Щоб представити число 1/3 як константу, використовуйте

#include x2

Уникайте цього використання:

#include x3

або:

#include x4

обгрунтування#

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

нотатки#

Якщо раціональний дріб подано у системі числення, в якій він має кінцеве, а не повторюване представлення, як 3#0.1# у наведеному вище прикладі, він може мати більшу точність при переведенні у машинну систему числення. (Це не стосується іменованих чисел, як у цьому прикладі - вони повинні бути обчислені точно).

Капіталізація#

настанова#

  • Зробіть зарезервовані слова та інші елементи програми візуально відмінними один від одного.

конкретизація#

  • Використовуйте малі літери для всіх зарезервованих слів (коли вони використовуються як зарезервовані).

  • Використовуйте змішаний регістр для всіх інших ідентифікаторів, велику літеру на початку кожного слова, відокремлену підкресленням.

  • Використовуйте великі літери для скорочень та акронімів (див. примітки щодо автоматизації).

приклад#

#include x5

обгрунтування#

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

Вибрана тут конкретизація призначена для того, щоб бути більш читабельною для досвідченого програміста Ada, якому не потрібні зарезервовані слова, щоб перескакувати зі сторінки на сторінку. Початківці в будь-якій мові часто вважають, що зарезервовані слова слід підкреслювати, щоб допомогти їм легше знаходити керуючі структури. Через це викладачі у класі та книжках, що знайомлять з мовою Ада, можуть розглянути альтернативний варіант. У довідковому посібнику з Ади (1995) для всіх зарезервованих слів вибрано напівжирне написання малих літер.

примітки щодо автоматизації#

Імена в Ada не чутливі до регістру. Тому імена max_limit, MAX_LIMIT і Max_Limit позначають один і той самий об'єкт або сутність. Хороший форматер коду повинен вміти автоматично перетворювати один стиль в інший, якщо слова розділяються підкресленнями.

Як рекомендовано в Настанові 3.1.4, скорочення повинні бути єдиними для всього проекту. Автоматизований інструмент повинен дозволяти проекту визначати ці абревіатури та форматувати їх відповідним чином.

Скорочення#

настанова#

  • Не використовуйте абревіатуру довгого слова як ідентифікатор, якщо існує коротший синонім.

  • Використовуйте послідовну стратегію скорочень.

  • Не використовуйте двозначні абревіатури.

  • Щоб виправдати своє використання, абревіатура повинна економити багато символів порівняно з повним словом.

  • Використовуйте абревіатури, які є загальноприйнятими у сфері застосування.

  • Ведіть список прийнятих скорочень і використовуйте тільки ті, що є в цьому списку.

приклад#

Використовуй:

#include x6

замість того, щоб:

#include x7

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

#include x8

обгрунтування#

Багато абревіатур є двозначними або незрозумілими, якщо їх не розглядати в контексті. Наприклад, Temp може означати як час, так і температуру. З цієї причини слід ретельно обирати абревіатури, коли ви їх використовуєте. Обґрунтування в Настанові 8.1.2 надає більш ретельне обговорення того, як контекст повинен впливати на використання скорочень.

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

Ви можете встановити скорочений формат для повної назви за допомогою пункту перейменування. Ця можливість є корисною, коли дуже довга повна назва може зустрічатися багато разів у локалізованій частині коду (див. Настанову 5.7.2).

Список прийнятих скорочень для проекту надає стандартний контекст для використання кожного скорочення.

Угоди про іменування#

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

Імена#

настанова#

  • Обирайте імена, які є максимально самодокументуючими.

  • Використовуйте короткий синонім замість абревіатури (див. Настанову 3.1.4).

  • Використовуйте імена, вказані в заявці, але не використовуйте незрозумілий жаргон.

  • Не використовуйте одне й те саме ім'я для оголошення різних типів ідентифікаторів.

приклад#

У програмі для роботи з деревами використання назви Left замість Left_Branch є достатнім для передачі повного значення, враховуючи контекст. Однак замість TOD використовуйте Time_Of_Day.

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

#include x9

При використанні дочірніх пакунків невдалий вибір назв пакунків, підпакунків та ідентифікаторів може призвести до конфлікту видимості з підпакунками. Див. у Обґрунтуванні (1995, §8.1) приклад отриманого, досить незрозумілого коду.

обгрунтування#

Програму, яка відповідає цим рекомендаціям, легше зрозуміти. Самодокументуючі імена потребують менше пояснювальних коментарів. Емпіричні дослідження показали, що ви можете ще більше покращити розуміння, якщо імена змінних не будуть надмірно довгими (Schneiderman 1986, 7). Контекст і застосування можуть суттєво допомогти. Одиниця виміру для числових сутностей може бути джерелом назв підтипів.

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

нотатки#

Дивіться Настанову 8.1.2 для обговорення того, як використовувати сферу застосування як орієнтир для вибору скорочень.

Імена підтипів#

настанова#

  • Використовуйте загальні іменники в однині як ідентифікатори підтипів.

  • Виберіть ідентифікатори, які описують одне із значень підтипу.

  • Подумайте про використання суфіксів для ідентифікаторів підтипів, які визначають видимі типи доступу, видимі піддіапазони або видимі типи масивів.

  • Для закритих типів не використовуйте конструкції ідентифікаторів (наприклад, суфікси), які є унікальними для ідентифікаторів підтипів.

  • Не використовуйте назви підтипів з попередньо визначених пакунків.

приклад#

#include x10

Зокрема, Day слід використовувати замість Days або Day_Type.

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

#include x11

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

обгрунтування#

При використанні цього стилю та запропонованого стилю для ідентифікаторів об'єктів програмний код більше нагадує англійську мову (див. Настанову 3.2.3). Крім того, цей стиль узгоджується з назвами попередньо визначених ідентифікаторів мови. Вони не називаються Integers, Booleans, Integer_Type або Boolean_Type.

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

нотатки#

У цьому посібнику зі стилю намагаються дотримуватися стандарту Ada Reference Manual (1995) у використанні термінів "тип" і "підтип". Загалом, "тип" відноситься до абстрактного поняття, як у оголошенні типу, тоді як "підтип" відноситься до імені, яке дається цьому абстрактному поняттю у реальному оголошенні. Таким чином, те, що в Ада 83 (Ada Reference Manual 1983) називалося ім'ям типу, тепер називається ім'ям підтипу.

Назви об'єктів#

настанова#

  • Використовуйте присудки або прикметники для булевих об'єктів.

  • Використовуйте конкретні іменники в однині як ідентифікатори об'єктів.

  • Виберіть ідентифікатори, які описують значення об'єкта під час виконання.

  • Використовуйте загальні іменники в однині як ідентифікатори компонентів запису.

приклад#

Небулеві об'єкти:

#include x12

Булеві об'єкти:

#include x13

обгрунтування#

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

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

#include x14

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

#include x15

нотатки#

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

Іменування тегованих типів і пов'язаних з ними пакунків#

настанова#

  • Використовуйте узгоджену угоду про імена для тегованих типів і пов'язаних з ними пакунків.

конкретизація#

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

  • Називайте типи тегів так само, як і назви підтипів (див. Настанову 3.2.2).

  • Використовуйте префікс Abstract_ для пакунків, які експортують абстракцію, для якої ви маєте намір надати декілька реалізацій (див. Настанову 9.2.4).

  • Використовуйте суфікс _Mixin для пакунків, які надають одиниці функціональності, що можуть бути "додані" до основних абстракцій.

Друга інстанція підкреслює використання об'єктно-орієнтованих функцій за допомогою спеціальних імен або суфіксів:

  • Називайте пакунки класів за назвою об'єкта, який вони представляють, без суфікса (Розен 1995).

  • Називайте пакети міксінів за назвою грані, яку вони представляють, додаючи суфікс _Facet (Rosen 1995).

  • Назвіть основний тегований тип Instance (Розен 1995).

  • Після оголошення конкретного типу слідує оголошення підтипу з іменем Class для відповідного загальнокласового типу (Розен 1995).

приклад#

Наступний приклад з "Обґрунтування" (1995, §§4.4.4 і 4.6.2), що складається з двох частин, застосовує конвенції іменування першої інстанції.

У першій частині цього прикладу припустимо, що тип Set_Element було оголошено деінде:

#include x16

У другій частині цього прикладу застосовано угоду про іменування до пакунків mixin, які підтримують віконну систему:

#include x17

У наступному прикладі застосовано конвенції іменування другої інстанції, як описано в Rosen (1995):

#include x18

Зразки декларацій можуть виглядати так:

#include x19

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

обгрунтування#

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

нотатки#

Угода про імена для класів проводить чітку межу між об'єктно-орієнтованими абстракціями та іншими видами абстракцій. Враховуючи, що інженери визначали абстрактні типи даних у мові Ада 83 (Ada Reference Manual 1983) понад 10 років, ви не повинні змінювати угоду про імена лише заради використання розширення типу за допомогою типу. Ви повинні враховувати, наскільки важливим є виокремлення випадків успадкування у загальному використанні абстракцій у вашій програмі. Якщо ви надаєте перевагу абстракції в цілому, а не механізму, який використовується для реалізації абстракції (тобто, успадкування, розширення типів та поліморфізм), ви можете не застосовувати таку сувору угоду щодо іменування. Ви не погіршуєте якість, надаючи перевагу більш плавному переходу від абстракцій, розроблених без успадкування, до абстракцій, розроблених із успадкуванням.

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

Назви програмних блоків#

настанова#

  • Використовуйте дієслова дії для процедур і записів.

  • Використовуйте предикати для булевих функцій.

  • Використовуйте іменники для небулевих функцій.

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

  • Дайте завданням назви, які передбачають активну сутність.

  • Використовуйте іменники, що описують дані, які захищаються, для захищених одиниць.

  • Називайте узагальнені підпрограми так, як якщо б вони були не узагальненими підпрограмами.

  • Називайте загальні пакунки так, як якщо б вони були нетиповими.

  • Зробіть загальні назви більш загальними, ніж конкретні назви.

приклад#

Нижче наведено приклади назв елементів, з яких складається програма на мові Ада:

Приклади назв процедур:

#include x20

Приклади назв функцій для функцій з булевими значеннями:

#include x21

Приклади назв функцій, що не мають булевих значень:

#include x22

Приклади назв пакунків:

#include x23

Зразок об'єктів, що охороняються:

#include x24

Приклади назв завдань:

#include x25

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

#include x26

Коли пакунки та їхні підпрограми називаються разом, результуючий код є дуже описовим:

#include x27

обгрунтування#

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

Дивіться також Настанову 3.2.4 щодо використання суфіксів спеціального призначення у пакунках, пов'язаних з тегованими типами.

нотатки#

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

Константи та іменовані числа#

настанова#

  • Використовуйте символьні значення замість літералів, якщо символьні значення покращують читабельність.

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

  • Використовуйте попередньо визначені константи Ada.Numerics.Pi та Ada.Numerics.e для математичних констант Pi та e.

  • Використовуйте константи замість змінних для постійних значень.

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

  • Використовуйте іменовані числа замість констант, коли це можливо.

  • Використовуйте іменовані числа для заміни числових літералів, тип або контекст яких є дійсно універсальним.

  • Використовуйте константи для об'єктів, значення яких не можуть змінюватися після розробки (United Technologies 1987).

  • Покажіть зв'язки між символьними значеннями, визначивши їх за допомогою статичних виразів.

  • Використовуйте лінійно незалежні набори літералів.

  • Використовуйте атрибути типу "Перший" та "Останній" замість літералів, де це можливо.

приклад#

#include x28

Оголошення Pi іменованим числом (з використанням оператораwithдля стандартного пакету Ada.Numerics у довіднику Ada [1995, §A.5]) дозволяє посилатися на нього символічно у наведеному нижче операторі присвоювання:

#include x29

замість того, щоб

#include x30

Крім того, Ada.Characters.Latin_1.Bel більш виразний, ніж Character'Val(8#007#).

Чіткість оголошення константних та іменованих чисел можна покращити, використовуючи інші константні та іменовані числа. Наприклад:

#include x31

є більш зрозумілим і простішим в обслуговуванні, ніж

#include x32

Наступні літерали повинні бути константами:

#include x33

обгрунтування#

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

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

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

Дивіться Настанову 4.1.4 для отримання додаткових вказівок щодо вибору безпараметричної функції в порівнянні з константою.

нотатки#

Існують ситуації, коли літерал є кращим вибором, ніж ім'я. Для цього необхідно виконати наступні умови:

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

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

Наприклад, літерали в наступному добре відомому співвідношенні є зрозумілими і незмінними:

#include x34

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

#include x35

Винятки#

настанова#

  • Використовуйте назву, яка вказує на тип проблеми, яку представляє виняток.

приклад#

#include x36

обгрунтування#

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

Конструктори#

настанова#

  • Додавайте префікс New, Make або Create до конструкторів імен (у цьому сенсі - операцій зі створення та/або ініціалізації об'єкта).

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

конкретизація#

  • Назвіть дочірній пакет, що містить конструктори <whatever>.Constructor.

приклад#

#include x37

обгрунтування#

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

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

Для отримання інформації про використання конструкторів Ada зверніться до Настанови 9.3.3.

Коментарі#

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

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

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

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

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

Загальні зауваження#

настанова#

  • Зробіть код максимально зрозумілим, щоб зменшити потребу в коментарях.

  • Ніколи не повторюйте в коментарях інформацію, яка легко доступна в коді.

  • Якщо коментар необхідний, зробіть його стислим і повним.

  • Використовуйте правильну граматику та орфографію в коментарях.

  • Робіть коментарі візуально відмінними від коду.

  • Структуруйте коментарі в заголовку так, щоб інформація могла бути автоматично вилучена інструментом.

обгрунтування#

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

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

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

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

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

примітки щодо автоматизації#

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

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

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

Заголовки файлів#

настанова#

  • Додайте заголовок до кожного вихідного файлу.

  • У заголовку файлу додайте інформацію про власника, відповідальність та історію файлу.

конкретизація#

  • Додайте до заголовка файлу повідомлення про авторські права.

  • У заголовку файлу вказуйте ім'я автора та назву підрозділу.

  • Додайте історію ревізій до заголовка файлу, включаючи короткий опис кожної зміни, дату та ім'я особи, яка внесла зміну.

приклад#

#include x38

обгрунтування#

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

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

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

нотатки#

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

Заголовки специфікацій програмних блоків#

настанова#

  • Додайте заголовок до специфікації кожного програмного блоку.

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

  • Не повторюйте в заголовку специфікації інформацію (крім назви пристрою), яка присутня в специфікації.

  • Поясніть, що робить пристрій, а не як і чому він це робить.

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

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

  • Опишіть робочі (часові та просторові) характеристики пристрою.

конкретизація#

  • Поставте назву програмного блоку в заголовку.

  • Коротко поясніть мету програмного блоку.

  • Для пакетів опишіть вплив видимих підпрограм одна на одну і те, як їх слід використовувати разом.

  • Перелічіть усі винятки, які можуть бути підняті підрозділом.

  • Перелічіть всі глобальні ефекти пристрою.

  • Перелічіть передумови та постумови створення підрозділу.

  • Перелік прихованих завдань, активованих пристроєм.

  • Не перераховуйте імена параметрів підпрограми.

  • Не перераховуйте назви підпрограм пакунка лише для того, щоб їх перерахувати.

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

  • Не перераховуйте назви всіх інших підрозділів, які використовують цей пристрій.

приклад#

#include x39

обгрунтування#

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

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

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

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

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

нотатки#

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

винятки#

Якщо група програмних блоків тісно пов'язана або проста для розуміння, допустимо використовувати один заголовок для всієї групи програмних блоків. Наприклад, має сенс використовувати один заголовок для опису поведінки функцій Max і Min; функцій Sin, Cos і Tan; або групи функцій для запиту пов'язаних атрибутів об'єкта, інкапсульованого в пакеті. Це особливо актуально, коли кожна функція у наборі здатна згенерувати однакові винятки.

Керівники структурних підрозділів програми#

настанова#

  • У тілі заголовка розмістіть інформацію, необхідну супровіднику програмного блоку

  • Поясніть, як і чому пристрій виконує свою функцію, а не що він робить.

  • Не повторюйте в заголовку інформацію (крім назви пристрою), яка є очевидною при читанні коду.

  • Не повторюйте в заголовку тіла інформацію (крім назви пристрою), яка є в заголовку специфікації.

конкретизація#

  • Поставте назву програмного блоку в заголовку.

  • Записуйте проблеми з переносимістю в заголовку.

  • Узагальнюйте складні алгоритми в заголовку.

  • Записуйте причини важливих або суперечливих рішень щодо впровадження.

  • Записуйте відкинуті альтернативи реалізації разом із причиною їх відкидання.

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

приклад#

#include x40

обгрунтування#

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

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

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

нотатки#

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

#include x41

і:

#include x42

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

Коментарі до даних#

настанова#

  • Коментуйте всі типи даних, об'єкти та винятки, якщо тільки їхні назви не є зрозумілими.

  • Включити інформацію про семантичну структуру складних структур даних на основі вказівників.

  • Включіть інформацію про зв'язки, які підтримуються між об'єктами даних.

  • Опускайте коментарі, які просто повторюють інформацію в назві.

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

приклад#

Об'єкти можна групувати за призначенням і коментувати як:

#include x43

Умови, за яких робиться виняток, повинні бути прокоментовані:

#include x44

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

#include x45

обгрунтування#

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

У першому прикладі, наведеному вище, назви Поточний_Стовпець і Поточний_Рядок є відносно зрозумілими. Назва Бажаний_стовпчик також вдало підібрана, але вона залишає читача здивованим, який зв'язок між поточним стовпчиком і бажаним стовпчиком. Коментар пояснює причину наявності обох стовпців.

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

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

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

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

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

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

Заява Коментарі#

настанова#

  • Мінімізуйте коментарі, вбудовані між твердженнями.

  • Використовуйте коментарі лише для пояснення неочевидних частин коду.

  • Коментуйте навмисні пропуски в коді.

  • Не використовуйте коментарі для перефразування коду.

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

  • Якщо коментарі необхідні, зробіть так, щоб вони візуально відрізнялися від коду.

приклад#

Нижче наведено приклад дуже погано закоментованого коду:

#include x46

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

#include x47

обгрунтування#

Покращення, показані в прикладі, не є покращеннями просто за рахунок зменшення загальної кількості коментарів; вони є покращеннями за рахунок зменшення кількості непотрібних коментарів.

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

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

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

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

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

Див. також Настанову 9.3.1 для обговорення того, яку документацію ви повинні надати щодо типів міток і переадресації.

нотатки#

Наведений вище приклад можна вдосконалити, оголосивши змінні Count і Sum у локальному блоці так, щоб їхня область видимості була обмеженою, а ініціалізація відбувалася поблизу їхнього використання, наприклад, назвавши блок Compute_Average або перемістивши код у функцію Average_Of. Обчислення Max_Number також можна відокремити від обчислення Average. Однак ці зміни є предметом інших настанов; цей приклад лише ілюструє правильне використання коментарів.

Коментарі до маркерів#

настанова#

  • Використовуйте маркери нумерації сторінок для позначення меж програмних блоків (див. Настанову 2.1.7).

  • Повторіть назву модуля у коментарі, щоб позначити початок тіла пакунка, підпрограми, завдання або блоку, якщо початку передують оголошення.

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

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

приклад#

#include x48

обгрунтування#

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

Оператори if, elsif, else та end if інструкції if часто розділені довгими послідовностями операторів, іноді з іншими інструкціями if. Як показано в першому прикладі, маркерні коментарі підкреслюють зв'язок ключових слів одного й того ж оператора на великій візуальній відстані. Коментарі-маркери не потрібні для операторів блоку та циклу, оскільки синтаксис цих операторів дозволяє називати їх іменами, що повторюються в кінці. Використання таких імен краще, ніж використання маркерних коментарів, оскільки компілятор перевіряє, чи збігаються імена на початку і в кінці.

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

нотатки#

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

Використання типів#

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

Типи декларування#

настанова#

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

  • Шукайте інформацію про можливі значення в додатку.

  • Не використовуйте повторно жодну з назв підтипів у пакунку Standard.

  • Використовуйте оголошення підтипів для покращення читабельності програми (Booch 1987).

  • Використовуйте похідні типи та підтипи разом (див. Настанову 5.3.1).

приклад#

#include x49

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

#include x50

обгрунтування#

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

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

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

Ви можете перейменувати тип, оголосивши підтип без обмежень (Ada Reference Manual 1995, §8.5). Ви не можете перевантажувати ім'я підтипу; перевантаження застосовується лише до сутностей, які можна викликати. Літерали перечислення розглядаються як функції без параметрів і тому включені у це правило.

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

нотатки#

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

Будь-яке відхилення від цієї настанови применшує переваги потужних засобів введення мови Ада.

винятки#

Бувають випадки, коли ви не маєте певної залежності від якогось діапазону числових значень. Такі ситуації трапляються, наприклад, з індексами масиву (наприклад, список, розмір якого не фіксується жодною конкретною семантикою). Дивіться Настанову 7.2.1 для обговорення належного використання наперед визначених типів.

Типи перерахувань#

настанова#

  • Використовуйте типи зчислення замість числових кодів.

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

приклад#

Використовуй:

#include x51

замість того, щоб:

#include x52

і додайте наступне, якщо потрібно:

#include x53

обгрунтування#

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

Крім того, Ада надає ряд атрибутів ('Pos, 'Val, 'Succ, 'Pred, 'Image та 'Value) для типів зчислення, які є більш надійними, ніж операції над кодуваннями, написані користувачем.

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

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

Підсумок#

правопис#

  • Використовуйте підкреслення, щоб відокремити слова у складній назві.

  • Послідовно зображуйте числа.

  • Представляти літерали у радіксі, що відповідає задачі.

  • Використовуйте підкреслення для розділення цифр так само, як у звичайному тексті використовуються коми або крапки (або пробіли для не десяткових основ).

  • Використовуючи наукову термінологію, послідовно робіть "Е" або великими, або малими літерами.

  • В альтернативній системі числення подайте літери або всіма великими, або всіма малими літерами.

  • Зробіть зарезервовані слова та інші елементи програми візуально відмінними один від одного.

  • Не використовуйте абревіатуру довгого слова як ідентифікатор, якщо існує коротший синонім.

  • Використовуйте послідовну стратегію скорочень.

  • Не використовуйте двозначні абревіатури.

  • Щоб виправдати своє використання, абревіатура повинна економити багато символів порівняно з повним словом.

  • Використовуйте абревіатури, які є загальноприйнятими у сфері застосування.

  • Ведіть список прийнятих скорочень і використовуйте тільки ті, що є в цьому списку.

Угоди про іменування#

  • Обирайте імена, які є максимально самодокументуючими.

  • Використовуйте короткий синонім замість абревіатури.

  • Використовуйте імена, вказані в заявці, але не використовуйте незрозумілий жаргон.

  • Не використовуйте одне й те саме ім'я для оголошення різних типів ідентифікаторів.

  • Використовуйте загальні іменники в однині як ідентифікатори підтипів.

  • Виберіть ідентифікатори, які описують одне із значень підтипу.

  • Подумайте про використання суфіксів для ідентифікаторів підтипів, які визначають видимі типи доступу, видимі піддіапазони або видимі типи масивів.

  • Для закритих типів не використовуйте конструкції ідентифікаторів (наприклад, суфікси), які є унікальними для ідентифікаторів підтипів.

  • Не використовуйте назви підтипів з попередньо визначених пакунків.

  • Використовуйте присудки або прикметники для булевих об'єктів.

  • Використовуйте конкретні іменники в однині як ідентифікатори об'єктів.

  • Виберіть ідентифікатори, які описують значення об'єкта під час виконання.

  • Використовуйте загальні іменники в однині як ідентифікатори компонентів запису.

  • Використовуйте узгоджену угоду про імена для тегованих типів і пов'язаних з ними пакунків.

  • Використовуйте дієслова дії для процедур і записів.

  • Використовуйте предикати для булевих функцій.

  • Використовуйте іменники для небулевих функцій.

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

  • Дайте завданням назви, які передбачають активну сутність.

  • Використовуйте іменники, що описують дані, які захищаються, для захищених одиниць.

  • Називайте узагальнені підпрограми так, як якщо б вони були не узагальненими підпрограмами.

  • Називайте загальні пакунки так, як якщо б вони були нетиповими.

  • Зробіть загальні назви більш загальними, ніж конкретні назви.

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

  • Використовуйте попередньо визначені константи Ada.Numerics.Pi та Ada.Numerics.e для математичних констант Pi та e.

  • Використовуйте константи замість змінних для постійних значень.

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

  • Використовуйте іменовані числа замість констант, коли це можливо.

  • Використовуйте іменовані числа для заміни числових літералів, тип або контекст яких є дійсно універсальним.

  • Використовуйте константи для об'єктів, значення яких не можуть змінюватися після розробки. (United Technologies 1987).

  • Покажіть зв'язки між символьними значеннями, визначивши їх за допомогою статичних виразів.

  • Використовуйте лінійно незалежні набори літералів.

  • Використовуйте атрибути типу "Перший" та "Останній" замість літералів, де це можливо.

  • Використовуйте назву, яка вказує на тип проблеми, яку представляє виняток.

  • Додавайте префікс New, Make або Create до конструкторів імен (у цьому сенсі - операцій зі створення та/або ініціалізації об'єкта).

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

коментарі#

  • Зробіть код максимально зрозумілим, щоб зменшити потребу в коментарях.

  • Ніколи не повторюйте в коментарях інформацію, яка легко доступна в коді.

  • Якщо коментар необхідний, зробіть його стислим і повним.

  • Використовуйте правильну граматику та орфографію в коментарях.

  • Робіть коментарі візуально відмінними від коду.

  • Структуруйте коментарі в заголовках так, щоб інформація могла бути автоматично вилучена інструментом.

  • Додайте заголовок до кожного вихідного файлу.

  • У заголовку файлу додайте інформацію про власника, відповідальність та історію файлу.

  • Додайте заголовок до специфікації кожного програмного блоку.

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

  • Не повторюйте в заголовку специфікації інформацію (крім назви пристрою), яка присутня в специфікації.

  • Поясніть, що робить пристрій, а не як і чому він це робить.

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

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

  • Опишіть робочі (часові та просторові) характеристики пристрою.

  • Помістіть інформацію, необхідну супровіднику програмного блоку, у заголовок тіла.

  • Поясніть, як і чому пристрій виконує свою функцію, а не що він робить.

  • Не повторюйте в заголовку інформацію (крім назви пристрою), яка є очевидною при читанні коду.

  • Не повторюйте в заголовку тіла інформацію (крім назви пристрою), яка є в заголовку специфікації.

  • Коментуйте всі типи даних, об'єкти та винятки, якщо тільки їхні назви не є зрозумілими.

  • Включити інформацію про семантичну структуру складних структур даних на основі вказівників.

  • Включіть інформацію про зв'язки, які підтримуються між об'єктами даних.

  • Опускайте коментарі, які просто повторюють інформацію в назві.

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

  • Мінімізуйте коментарі, вбудовані між твердженнями.

  • Використовуйте коментарі лише для пояснення неочевидних частин коду.

  • Коментуйте навмисні пропуски в коді.

  • Не використовуйте коментарі для перефразування коду.

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

  • Якщо коментарі необхідні, зробіть так, щоб вони візуально відрізнялися від коду.

  • Використовуйте маркери нумерації сторінок для позначення меж програмних блоків.

  • Повторіть назву модуля у коментарі, щоб позначити початок тіла пакунка, підпрограми, завдання або блоку, якщо початку передують оголошення.

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

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

з використанням типів#

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

  • Шукайте інформацію про можливі значення в додатку.

  • Не використовуйте повторно жодну з назв підтипів у пакунку Standard.

  • Використовуйте оголошення підтипів для покращення читабельності програми (Booch 1987).

  • Використовуйте похідні типи та підтипи разом.

  • Використовуйте типи зчислення замість числових кодів.

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

Ця сторінка "Ada Quality and Style Guide" адаптована з оригінальної роботи за адресою https://en.wikibooks.org/wiki/Ada_Style_Guide, яка доступна за ліцензією Creative Commons Attribution-ShareAlike License; можуть діяти додаткові умови. Сторінка не схвалена Вікікнигами або авторами Вікікниги "Ada Style Guide". Ця сторінка ліцензована за тією ж ліцензією, що й оригінальна робота.