Вирішив на всяк випадок зібрати свої переклади кількарічної давнини на цьому блозі, щоб не загубились якщо що. Нижче – перша ластівка – переклад статті “CStupidClassName” від Dejan Jelovic. За пару годин ще пару перепощу – може комусь стане в нагоді.
Я занадто часто зустрічаю класи, ім’я яких починається з великої літери ‘C’. CMainWindow. CParameters. CSecurity. CThis. CThat. Це безумство потрібно припиняти!А розпочалося все з легкої руки компанії Borland. Вони тільки-но додали об’єкти до свого компілятора Turbo Pascal і хотіли постачати його з великою бібліотекою класів.
Зараз менеджери Borland можуть бути повними йолопами, але їхні інженери свого часу були дуже навіть нічого. Вони знали про можливі перешкоди на шляху до впровадження. В той час як вони постачали б велику бібліотеку класів зі звичайними іменами типу Time чи String, деякі з їх клієнтів могли вже використовувати записи (record, паскалевський аналог структур мови Сі) з іменами Time та String і таким чином вони не змогли б скомпілювати свої програми новою версією компілятора. Але коли ви зайнятий розробник ПЗ і дедлайн вже на носі, то вам не до того, аби витрачати цілий день на пошук та усунення проблем з новим компілятором. Ви просто плюнете на все і повернетесь до старого.
Інженери Borland знайшли як розв’язати цю проблему: вони дописали до кожного класу велику літеру ‘T’. От так ми отримали TWindow, TTime, TString і таке інше.
Звісно, в Borland очікували, що люди продовжать користуватись звичайними іменами класів без великої літери ‘T’. Або, у випадку інших постачальників бібліотек, використовуватимуться інші великі літери. Це зменшило б шанс колізій, коли дві бібліотеки використовували б одну й ту саму велику літеру і одне й те саме ім’я класу.
Але ж програмісти – народ зайнятий. Вони часто приймають нововведення своїх постачальників софту за нове віяння. Тож коли вони побачили, що Borland використовує велику ‘T’ для іменування своїх класів, то вирішили, що цьому була якась поважна причина і то є добре. Інакше розумні програмісти в Borland цього не зробили б, правда ж?
Це, звісно, і звело нанівець всі зусилля. Так, Borland змогла постачати першу версію своєї бібліотеки не викликавши помилок компіляції існуючих вихідних кодів, але як тільки поширилась практика використання великої літери ‘T’ кожна нова версія бібліотеки таки стикалась з цими проблемами.
Тож в довгостроковій перспективі додавання великої ‘T’ не принесло нічого доброго.
Microsoft вступає в бій
Далі йде Microsoft. Оскільки вони мали на озброєнні лише компілятор C, то почали швидко поступатись своїми позиціями на ринку Borland C++ і змушені були розробити свій компілятор C++ і свою бібліотеку класів. Їх спіткала та ж сама проблема, що і Borland пару років тому: якщо вони постачатимуть новий компілятор і C++ він не зможе компілювати існуючий C-код своїх покупців, то в них будуть великі проблеми.
І що ж вони зробили? Вони додали велику літеру ‘C’ до імені кожного класу, який вони постачали зі своїм компілятором.
І знову реакція користувачів не забарилась: вони почали додавати велику ‘C’ до імені кожного класу і знову ж ця хитрість була переможена.
От і живемо ми у світі класів з великої літери ‘C’.
Що нам робити?
По-перше, здоровий глузд підказує, що варто відмовитись від використання великої ‘C’ для ваших імен класів. Оскільки всі використовують її, то таким чином ви зменшите шанс конфлікту імен.
По-друге, ознайомтесь з просторами імен (namespaces) і починайте правильно їх використовувати.
А хіба велика ‘C’ не корисна для розрізнення класів?
А хіба різниця між класом та структурою настільки важлива для людини, яка їх використовує? Ви можете знайти хоч один приклад, коли варто враховувати цю різницю?
В C++ коді корисним буде розрізняти тільки дві речі:
- Чи є ім’я типом даних, чи функцією?
- Є змінна змінною класу, або змінною функції?
Перше розрізнення корисне, коли ви дивитесь код з оголошеннями, наприклад:
something (2); // це функція, чи тимчасова змінна?
Друге необхідне для того, щоб уникати неправильного використання змінних в функції.
Так що мені використовувати?
Використовуйте принцип бритви Оккама. Наприклад, багато людей з комітету стандартизації C++ використовують наступні узгодження імен:
- назви типів даних починаються з великої літери
- імена змінних та функцій починаються з літер в нижньому регістрі
- імена змінних класу закінчуються символом підкреслення
Наприклад:
class MyClass
{
public:
MyClass (int numYears) { numYears_ = numYears; }
void setYears (int numYears) { numYears_ = numYears; }
int getYears () { return numYears_; }
private:
int numYears_;
};
Альтернативою правила №3 може бути використання узгодження притаманного Microsoft, яке полягає у додаванні префіксу “m_” до змінних – членів класу. Таким чином змінна в прикладі вище називатиметься не numYears_
, а m_numYears
. Обидва варіанти є гарними.
Відгук
Декілька днів тому я отримав повідомлення від Ернесто Гуісадо (Ernesto Guisado), який повідомляв мене про те, що я помилявся, коли думав, що Borland була першою широковідомою компанією, яка почала використовувати велику ‘T’. Ось його електронне повідомлення:
From: Ernesto Guisado
To: "Dejan Jelovic"
Добридень, Я саме прочитав вашу статтю (http://www.jelovic.com/articles/stupid_naming.htm).
Я погоджуюсь з гарно висловленими вами думками у статті,
але маю вказати на помилку: "А розпочалося все з легкої руки компанії Borland"
Знайдіть на http://developer.apple.com/tools/macapp/macapp_advantages.html
наступні рядки: "Версії MacApp 1 та 2 були написані на Object Pascal.
На початку 90-х MacApp було портовано на C++ і результат мав версію 3.0."
MacApp був переповнений TApplication, TWindow, ... А це було ще в 1986-му.
Borland'івський OWL було створено спільнотою Whitewater, яка також
створила мову Actor. Actor нагадує Smalltalk із синтаксисом Pascal/C,
тож там могли теж бути посилання на TFoo. Дивіться також:
http://www.applefritter.com/lisa/texts/Lisa_ToolKit_3_0_Sources.pdf
Він був створений для Apple Lisa (написаної на Clascal) і вже використовував
TByte, TOctet, ... Цей "Apple Lisa Toolkit 3.0 Source Code Listing"
(29/1012) має цікавий рядок: TByte = -128..127; {Ці T-імена потрібні
для того, щоб програмісти МОГЛИ використовувати UObject, НЕ МОГЛИ
використовувати UClascal, і використовувати "Byte"} Це може бути
підтвердженням вашої теорії!
З повагою,
Ернесто.