Функции и методи

Ако се наложи, при грешка в тялото на дадена функция или метод може лесно и безболезнено да го заменим с напълно друг код, стига да не променим името му, както и типа на аргументите и връщаната стойност. За разлика от това, промяната на името изисква поправки, които не са локализирани на едно място и затова много по-лесно могат да доведат до грешки.

Разбира се недопустимо е името на функция или метод да бъде нищо не значещото foo или bar. Според Линус Торвалдс [TorCS] “to call a global function foo is a shooting offense.” А според GNU Coding Standards [Sta2001, chapter 5.4] “The names of global variables and functions in a program serve as comments of a sort. So don't choose terse names—instead, look for names that give useful information about the meaning of the variable or function.

При избора на име, трябва да се стараем то да изразява това какво прави функцията или метода, а не как го прави. Макар на теория това да е ясно, лесно е да се объркаме, защото когато пишем дадена функция или метод, вниманието ни е заето основно с това как да кодираме тялото им, а не как впоследствие те ще бъдат използвани.

Трябва да се стремим имената на функциите да се състоят от до три думи, най-често само от две. Имената на методите обаче съдържат с една дума по-малко — до две думи, а най-често само една. Причината за това различие е това, че в имената на методите не бива да включваме името на класа, защото той се подразбира. Например една функция за затваряне на прозорец може да наречем close_window(…) или CloseWindow(…). Няма смисъл обаче да наречем по същия начин аналогичен метод, можем да го наречем просто close(…), защото е ясно, че обектът е прозорец.

Горното правило не е универсално приложимо. Все пак ако дадено име е твърде дълго, това най-често се дължи на това, че

За да поясним последното, ще дадем следния пример (по идея на Лео Броуди [Bro84]). Да предположим, че видим функция с име start_left_mottor. Макар, че името й съдържа до три думи, дължината му ни усъмнява, че може би тази функция трябва да се раздели на няколко по-прости. Ако обаче наред с тази функция видим още и следните

start_left_mottor()
start_left_magnet()
start_right_mottor()
start_right_magnet()
stop_left_mottor()
stop_left_magnet()
stop_right_mottor()
stop_right_magnet()
        

съмненията ни отпадат. Ясно става, че имаме някакво устройство, състоящо се от лява и дясна част. Всяка от тези части има мотор и магнит, които могат да се пускат и спират. Затова на Си++ бихме могли да имаме „ляв“ и „десен“ обект, на които да изпращаме следните съобщения:

mottor().start()
mottor().magnet().start()
magnet().stop()
        

По такъв начин имената, съдържащи три думи, се свеждат до по-прости, съставени само от една дума.

Бертран Мейер [Me97, chapter 26] дава следния полезен съвет за избора на имена[2]:

Routine names should faithfully reflect the Command-Query separation principle:

  • Procedures (commands) should be verbs in the infinitive or imperative, possibly with complements: make, move, deposit, set_color.

  • Attributes and functions (queries) should never be imperative or infinitive verbs; never call a query get_value, but just value. Non-boolean query names should be nouns, such as number, possibly qualified as in last_month_balance. Boolean queries should use adjectives, as in full. In English, because of possible confusions between adjectives and verbs (empty, for example, could mean “is this empty?” or “empty this!”), a frequent convention for boolean queries is the is_ form, as in is_empty.

Друг въпрос, който трябва да разгледаме, е това дали може да използваме съкращения. Разбира се ясно е, че неразбираеми съкращения са недопустими; въпросът е да ползваме ли съкращения, ако те ще бъдат разбираеми за всеки? Важен довод против използването на съкращения дори в този случай е следният — лесно е човек да забрави как точно е било съкратено името и да му се наложи да си припомня това. Т.е. макар съкратените имена да не пречат много при четене, когато се налага тези съкращения да бъдат употребявани, те определено създават затруднения. Дали името беше left или lft? Или пък беше само l?

Изключение от горното правило имаме в случай, че дадена дума се използва толкова често в интерфейса на дадена библиотека, че за потребителите няма да представлява проблем да научат това съкращение. В такъв случай обаче то трябва да се използва навсякъде, а не само на някои места.

Глобални променливи.  Глобалните и статични променливи: да не се ползват, а ако се наложи: се именоват по същите правила, както и функциите и методите. При Си++ със сигурност може да се избегне използването на такива променливи.

Избягване на конфликт между имената.  При Си: bib_ime или _bib_ime. При Си++: name spaces. Имената на локалните променливи трябва да са различни от имената на видимите методи.

Имената на методи при Смолтоук и Обджектив Си. ...



[2] Тук е използвана терминологията на Айфел: “procedures” са функциите, които не връщат стойност, “functions” са функциите, които връщат стойност, а “attributes” са променливите в класа.