nakov high quality code

73
Качествен Качествен програмен код програмен код Светлин Наков Национална академия по разработка на софтуер www.devbg.org

Upload: svetlin-nakov

Post on 20-Jun-2015

1.278 views

Category:

Technology


8 download

TRANSCRIPT

Page 1: Nakov High Quality Code

Качествен Качествен програмен кодпрограмен код

Светлин НаковСветлин НаковНационална академия по разработка на софтуерНационална академия по разработка на софтуер

www.devbg.orgwww.devbg.org

Page 2: Nakov High Quality Code

Лекторът Светлин НаковЛекторът Светлин Наков

• Директор на Национална академия по разработка на Директор на Национална академия по разработка на софтуер (НАРС)софтуер (НАРС)

• Безплатни курсове за програмисти – Безплатни курсове за програмисти – Java Java ии .NET .NET

• Обучение по стипендия + осигурена работаОбучение по стипендия + осигурена работа

• Председател на Българска асоциация на Председател на Българска асоциация на разработчиците на софтуер (БАРС)разработчиците на софтуер (БАРС)

• Преподавател по съвременни софтуерни технологии в Преподавател по съвременни софтуерни технологии в СУ "Св. Климент Охридски"СУ "Св. Климент Охридски"

• Консултант по разработка на софтуерКонсултант по разработка на софтуер

• Носител на наградата "Джон Атанасов" на президента Носител на наградата "Джон Атанасов" на президента на България за 2004на България за 2004

Page 3: Nakov High Quality Code

СъдържаниеСъдържание

• Дефиниция за качествен кодДефиниция за качествен код

• Софтуерен дизайнСофтуерен дизайн

• Висококачествени подпрограмиВисококачествени подпрограми

• Защитно програмиранеЗащитно програмиране

• Правилно използване на променливитеПравилно използване на променливите

• Имената на променливитеИмената на променливите

• Преработка на съществуващ кодПреработка на съществуващ код

• Самодокументиращ се кодСамодокументиращ се код

Page 4: Nakov High Quality Code

Какво е качествен Какво е качествен програмен код?програмен код?

Качествен програмен кодКачествен програмен код

Page 5: Nakov High Quality Code

Какво е качествен код?Какво е качествен код?

• Качеството на софтуера има 2 аспекта:Качеството на софтуера има 2 аспекта:

• Външно качество – видимото за потребителяВъншно качество – видимото за потребителя

• Коректност на софтуераКоректност на софтуера

• Удобство и леснота за работаУдобство и леснота за работа

• Производителност (скорост на работа)Производителност (скорост на работа)

• Вътрешно качество – вътрешната организация Вътрешно качество – вътрешната организация на архитектурата и програмния кодна архитектурата и програмния код

• РазбираемостРазбираемост

• Леснота за промяна и добавяне на Леснота за промяна и добавяне на функционалност (поддръжка)функционалност (поддръжка)

• Простота на реализациятаПростота на реализацията

Page 6: Nakov High Quality Code

Какво е качествен код?Какво е качествен код?

• Характеристики за качество на кода:Характеристики за качество на кода:

• КоректностКоректност

• Четимост и разбираемостЧетимост и разбираемост

• Висока свързаност на отговорноститеВисока свързаност на отговорностите (strong (strong cohesion)cohesion) на всички нива (модули, класове, методи) на всички нива (модули, класове, методи)

• Функционална независимост (Функционална независимост (loose coupling)loose coupling) на на всички нива (модули, класове, методи)всички нива (модули, класове, методи)

• Добро, консистентно форматиранеДобро, консистентно форматиране

• Подходящо и консистентно именуване на класовете, Подходящо и консистентно именуване на класовете, методите, променливите и останалите елементиметодите, променливите и останалите елементи

• Добра документация, вградена в кодаДобра документация, вградена в кода

Page 7: Nakov High Quality Code

Какво е качествен Какво е качествен софтуерен дизайн?софтуерен дизайн?

Качествен програмен кодКачествен програмен код

Page 8: Nakov High Quality Code

Софтуерен дизайнСофтуерен дизайн

• Качеството на софтуера силно зависи от Качеството на софтуера силно зависи от качеството на дизайнакачеството на дизайна

• Дизайнът е трудно-дефинируем процесДизайнът е трудно-дефинируем процес

• Итеративен, недетерминистиченИтеративен, недетерминистичен

• Няма точна рецепта как да се правиНяма точна рецепта как да се прави

• Основна цел на дизайна:Основна цел на дизайна:

• Да се управлява сложността на софтуераДа се управлява сложността на софтуера

• Основен похват при дизайна:Основен похват при дизайна:

• Функционална декомпозиция на проблемите на Функционална декомпозиция на проблемите на всички нивавсички нива

Page 9: Nakov High Quality Code

Какво е софтуерен дизайнКакво е софтуерен дизайн

• Софтуерният дизайн е:Софтуерният дизайн е:

• Принципна организация на софтуерната системаПринципна организация на софтуерната система

• Дизайнът се състои от:Дизайнът се състои от:

• Архитектурен планАрхитектурен план

• Описва основните компоненти и подсистеми на Описва основните компоненти и подсистеми на системата и взаимодействието между тяхсистемата и взаимодействието между тях

• Детайлен дизайнДетайлен дизайн

• Описва вътрешната организация на отделните Описва вътрешната организация на отделните компоненти и подсистемикомпоненти и подсистеми

• Описва класовете и методите в класоветеОписва класовете и методите в класовете

Page 10: Nakov High Quality Code

Характеристики на дизайнаХарактеристики на дизайна

• Минимална сложност, леснота за разбиранеМинимална сложност, леснота за разбиране

• Леснота за поддръжка (промяна и разширяване)Леснота за поддръжка (промяна и разширяване)

• Функционална независимост между подсистемите, Функционална независимост между подсистемите, компонентите и класовете (компонентите и класовете (loose couplingloose coupling))

• Преизползваемост (Преизползваемост (reusabilityreusability))

• ВисокВисокa a входна зависимост (входна зависимост (fan-infan-in))

• Някои Някои utilityutility класове класове се използват много честосе използват много често

• Ниска изходна зависимост (Ниска изходна зависимост (fan-outfan-out))

• Един клас да не ползва прекалено много други класовеЕдин клас да не ползва прекалено много други класове

• Минималност – да няма излишни частиМинималност – да няма излишни части

Page 11: Nakov High Quality Code

Процесът на дизайнПроцесът на дизайн

• Функционална декомпозиция:Функционална декомпозиция:

• Разделяме системата на подсистемиРазделяме системата на подсистеми

• Разделяме подсистемите на класове и ги Разделяме подсистемите на класове и ги подреждаме в пакетиподреждаме в пакети ( (пространства от имена)пространства от имена)

• Разделяме класовете в подпрограми (методи)Разделяме класовете в подпрограми (методи)

• Проектираме подпрограмите (чрез псевдокод)Проектираме подпрограмите (чрез псевдокод)

• Не е необходимо да се прави паралелно във Не е необходимо да се прави паралелно във всички посокивсички посоки

• Започва се от най-важната функционалност за Започва се от най-важната функционалност за клиентаклиента

Page 12: Nakov High Quality Code

Фази на дизайнаФази на дизайна

• Разделяне на подсистемите на класовеРазделяне на подсистемите на класове

• Идентификация на обектите и процесите от Идентификация на обектите и процесите от реалния святреалния свят

• Съпоставяне на класове за тези обектиСъпоставяне на класове за тези обекти

• Идентификация на връзките между обектитеИдентификация на връзките между обектите

• Проектиране на класова йерархияПроектиране на класова йерархия

• Използване на шаблони (Използване на шаблони (design patternsdesign patterns))

• Скриване на възможно най-много Скриване на възможно най-много имплементационни детайлиимплементационни детайли

Page 13: Nakov High Quality Code

Фази на дизайнаФази на дизайна

• Разделяне на класовете на методиРазделяне на класовете на методи• Идентификация на действията, които всеки Идентификация на действията, които всеки

обект може да извършва (методи)обект може да извършва (методи)

• Идентификация на съществените Идентификация на съществените характеристики на обектите (атрибути)характеристики на обектите (атрибути)

• Скриване на възможно най-много Скриване на възможно най-много имплементационни детайлиимплементационни детайли (private (private методи)методи)

• Максимална функционална независимостМаксимална функционална независимост (loose coupling)(loose coupling)

• Висока свързаност на отговорноститеВисока свързаност на отговорностите (strong (strong cohesion)cohesion)

Page 14: Nakov High Quality Code

Фази на дизайнаФази на дизайна

• Проектиране на вътрешността на Проектиране на вътрешността на методитеметодите

• Най-често е отговорност на програмистите, а Най-често е отговорност на програмистите, а не на архитектитене на архитектите

• Подбор на подходящи алгоритмиПодбор на подходящи алгоритми

• Описание на алгоритмите чрез псевдокодОписание на алгоритмите чрез псевдокод

Page 15: Nakov High Quality Code

Силата на диаграмитеСилата на диаграмите

Извикване на уеб услуга Изпълнение на SQL заявка

Резултат от SQL заявкаXML DataSetПроменени данни

във вид на XML DataSetЗаявки за нанасяне

на променитеКлиентWeb-услуга

База данни

Page 16: Nakov High Quality Code

Какво са качествените Какво са качествените подпрограми (методи)?подпрограми (методи)?

Качествен програмен кодКачествен програмен код

Page 17: Nakov High Quality Code

Защо да използваме методи?Защо да използваме методи?

• Намаляваме сложносттаНамаляваме сложността• Разбиваме сложните проблеми на по-простиРазбиваме сложните проблеми на по-прости

• Добавяме междинни нива на абстракцияДобавяме междинни нива на абстракция

• Скриваме детайли за имплементациятаСкриваме детайли за имплементацията

• Намаляваме риска от неуспехНамаляваме риска от неуспех

• Избягваме повторението на еднакъв кодИзбягваме повторението на еднакъв код

• Скриваме сложни последователности от Скриваме сложни последователности от действиядействия

• Скриваме работата с указателиСкриваме работата с указатели

• Опростяваме сложни булеви проверкиОпростяваме сложни булеви проверки

Page 18: Nakov High Quality Code

Свързаност на отговорноститеСвързаност на отговорностите

• Свързаност на отговорностите (strong Свързаност на отговорностите (strong cohesion) е ключово изискване за методитеcohesion) е ключово изискване за методите

• Генерален принцип: Един метод трябва да Генерален принцип: Един метод трябва да прави само едно нещо и да го прави добреправи само едно нещо и да го прави добре

• Операциите в един метод трябва да са Операциите в един метод трябва да са взаимосвързани – насочени към обща задачавзаимосвързани – насочени към обща задача

• Идеалният случай:Идеалният случай:

• Функционална кохезияФункционална кохезия

• Методът извършва единична ясно дефинирана Методът извършва единична ясно дефинирана операцияоперация

• Пример: функция Пример: функция SSqrt()qrt()

Page 19: Nakov High Quality Code

Допустими видове кохезияДопустими видове кохезия

• Последователна кохезияПоследователна кохезия• Редица от стъпки за решаване на единна задачаРедица от стъпки за решаване на единна задача

• Пример: Пример: SendEmail()SendEmail()1.1. свързваме се към сървъра за пощасвързваме се към сървъра за поща

2.2. изпращаме съобщениетоизпращаме съобщението

3.3. затваряме връзкатазатваряме връзката

• Комуникационна кохезияКомуникационна кохезия• Свързаност на действията по общи данниСвързаност на действията по общи данни

• Пример: Пример: DisplayReport()DisplayReport()1.1. извличаме даннитеизвличаме данните

2.2. форматираме гиформатираме ги

3.3. отпечатваме гиотпечатваме ги

Page 20: Nakov High Quality Code

Допустими видове кохезияДопустими видове кохезия

• Времева кохезияВремева кохезия

• Действия, които се извършват по едно и също Действия, които се извършват по едно и също времевреме

• Пример: Пример: LoadSettings()LoadSettings()

1.1. зареждаме настройките за шрифтоветезареждаме настройките за шрифтовете

2.2. зареждаме настройките за цветоветезареждаме настройките за цветовете

3.3. зареждаме настройките за принтеразареждаме настройките за принтера

4.4. зареждаме настройките за базата даннизареждаме настройките за базата данни

5.5. зареждаме настройките за Интернет достъпазареждаме настройките за Интернет достъпа

Page 21: Nakov High Quality Code

Недопустими видове кохезияНедопустими видове кохезия

• Логическа кохезияЛогическа кохезия

• Изпълнява се различно действие според някой Изпълнява се различно действие според някой входен параметър (код на операция)входен параметър (код на операция)

• Лош пример: Лош пример: ReadAll(int opReadAll(int op_code_code)) – прочита – прочита артикул, цена, адрес или ЕГНартикул, цена, адрес или ЕГН според подадения кодспоред подадения код

• Изключение: Обработчици на събития (event Изключение: Обработчици на събития (event handlers)handlers)

• Случайна кохезия (липса на свързаност)Случайна кохезия (липса на свързаност)

• Няколко несвързани едно с друго действияНяколко несвързани едно с друго действия

• Изключително лоша практика!Изключително лоша практика!

Page 22: Nakov High Quality Code

Имената на методитеИмената на методите

• Името трябва да описва всичко, което методът Името трябва да описва всичко, което методът извършваизвършва

• Ако няма подходящо име, имаме лоша кохезияАко няма подходящо име, имаме лоша кохезия!!

• Избягвайте безлични и общи думичкиИзбягвайте безлични и общи думички

• Лош пример: Лош пример: HandleStuff()HandleStuff(), , ProcessData()ProcessData()

• Не използвайте цифри в иметоНе използвайте цифри в името

• Лош пример: Лош пример: ReadProfile1()ReadProfile1(), , ReadProfile2()ReadProfile2()

• Дължината на името трябва да е толкова дълга, Дължината на името трябва да е толкова дълга, колкото е необходимо (9-15 символа)колкото е необходимо (9-15 символа)

• Ако името е прекалено дълго, имаме лоша кохезияАко името е прекалено дълго, имаме лоша кохезия

• Използвайте английски езикИзползвайте английски език

Page 23: Nakov High Quality Code

Имената на методитеИмената на методите

• Имената на функциите трябва да описват Имената на функциите трябва да описват връщаната стойноствръщаната стойност• Пример: Пример: GetNumberOfProcessors()GetNumberOfProcessors()

• Имената на процедурите се съставят по схемата Имената на процедурите се съставят по схемата <глагол> + <обект><глагол> + <обект>

• Пример: Пример: PrintReport()PrintReport(), , LoadSettings()LoadSettings()

• Използвайте консистентно противоположноститеИзползвайте консистентно противоположностите• Пример: Пример: OpenFile()OpenFile() и и CloseFile()CloseFile()

• Лош пример: Лош пример: OpenFile()OpenFile() и и _descriptor_close()_descriptor_close()

• Използвайте конвенция за честите операцииИзползвайте конвенция за честите операции• Пример: Пример: GetName()GetName(), , GetAge()GetAge(), , SetName()SetName(), , SetAge()SetAge()

• Спазвайте конвенцията навсякъдеСпазвайте конвенцията навсякъде

Page 24: Nakov High Quality Code

Колко да са дълги методите?Колко да са дълги методите?

• Предпочитайте кратки методи (до един екран)Предпочитайте кратки методи (до един екран)

• Методите трябва да имат силна кохезияМетодите трябва да имат силна кохезия

• Това е много по-важно от дължината им!Това е много по-важно от дължината им!

• Методите трябва да са дълги "колкото трябва"Методите трябва да са дълги "колкото трябва"

• Не разделяйте на части даден метод само защото е Не разделяйте на части даден метод само защото е много дълъгмного дълъг

Page 25: Nakov High Quality Code

Параметрите на методитеПараметрите на методите

• Подреждайте параметрите в последователност Подреждайте параметрите в последователност ((<<входнивходни>>, <входно-изходни>, , <входно-изходни>, <<изходниизходни>>))

• Подреждайте консистентно параметрите при Подреждайте консистентно параметрите при методи с подобни параметриметоди с подобни параметри

• Използвайте всички параметриИзползвайте всички параметри

• Ако връщате статус или код за грешка, сложете Ако връщате статус или код за грешка, сложете този параметър последентози параметър последен

• Не използвайте параметрите като работни Не използвайте параметрите като работни променливи (не модифицирайте параметрите)променливи (не модифицирайте параметрите)

• Документирайте неочевидните допусканияДокументирайте неочевидните допускания

• Например мерната единица при подаване на числаНапример мерната единица при подаване на числа

Page 26: Nakov High Quality Code

Параметрите на методитеПараметрите на методите

• Ограничете броя на параметрите до около 7Ограничете броя на параметрите до около 7

• Човешкото съзнание не може да следи повече от 7 Човешкото съзнание не може да следи повече от 7 неща едновременно (знаехте ли това?)неща едновременно (знаехте ли това?)

• Разграничавайте входните от изходните Разграничавайте входните от изходните параметри (ако езикът не го поддържа)параметри (ако езикът не го поддържа)

• Кога да подаваме обект и кога няколко негови Кога да подаваме обект и кога няколко негови полета?полета?

• Съобразете се логически методът над какво работи Съобразете се логически методът над какво работи – над обекти или над съвкупност от стойности– над обекти или над съвкупност от стойности

• Подавайте параметрите в коректния им редПодавайте параметрите в коректния им ред

• Използвайте именувано извикване, ако се поддържаИзползвайте именувано извикване, ако се поддържа

Page 27: Nakov High Quality Code

Функция или процедураФункция или процедура

• Функция или процедура?Функция или процедура?

• Използвайте функция когато основната задача на Използвайте функция когато основната задача на метода е да изчисли и върне някаква стойностметода е да изчисли и върне някаква стойност

• Уверете се, че всеки път на изпълнение връща Уверете се, че всеки път на изпълнение връща стойностстойност

• Не връщайте указател към локални данниНе връщайте указател към локални данни

• Запазете в променлива стойността преди да я Запазете в променлива стойността преди да я върнете:върнете:

returnreturn days * hoursPerDay * ratePerHour; days * hoursPerDay * ratePerHour;

int salary = days * hoursPerDay * ratePerHour;int salary = days * hoursPerDay * ratePerHour;return salary;return salary;

Page 28: Nakov High Quality Code

Какво е защитно Какво е защитно програмиране?програмиране?

Качествен програмен кодКачествен програмен код

Page 29: Nakov High Quality Code

Защитно програмиранеЗащитно програмиране

• Защитно програмиране (Защитно програмиране (defensive programming)defensive programming)

• Насочено към защита на кода от некоректни Насочено към защита на кода от некоректни данниданни

• Пази кода от грешки, които никой не очакваПази кода от грешки, които никой не очаква

• Имплементира се чрез проверка на Имплементира се чрез проверка на коректността на всички входни данникоректността на всички входни данни

• данните, идващи от външни източнициданните, идващи от външни източници

• входните параметри на методитевходните параметри на методите

• Имплементира се чрез Имплементира се чрез assertions, assertions, изключения и изключения и други средства за управление на грешкидруги средства за управление на грешки

Page 30: Nakov High Quality Code

Проверки (Проверки (assertions)assertions)

• Проверките (Проверките (assertions) assertions) следят за различни следят за различни очаквания за състоянието на програматаочаквания за състоянието на програмата

• Улавят неочаквани входни параметри или Улавят неочаквани входни параметри или вътрешни състояниявътрешни състояния

• Силно улесняват откриването на грешки в кодаСилно улесняват откриването на грешки в кода

• Представляват изрази от вида:Представляват изрази от вида:assert(assert(условие, съобщениеусловие, съобщение__заза__грешка)грешка)

• Ако условието е нарушено, програмата завършва Ако условието е нарушено, програмата завършва аварийно и се отпечатва грешкатааварийно и се отпечатва грешката

• При При release release компилация се премахват от кодакомпилация се премахват от кода

• Много са полезни при големи и сложни проектиМного са полезни при големи и сложни проекти

Page 31: Nakov High Quality Code

Проверки (Проверки (assertions)assertions)

• Проверките на практика "документират" Проверките на практика "документират" скритите допускания, които кодът очакваскритите допускания, които кодът очаква

• Някои езици поддържатНякои езици поддържат assertions assertions, в другите , в другите можем да си ги реализираме самиможем да си ги реализираме сами

• Типични грешки, улавяни с Типични грешки, улавяни с assertions:assertions:

• Стойност Стойност NULLNULL на входен параметър на входен параметър

• Стойност извън допустимия диапазон за входен Стойност извън допустимия диапазон за входен параметърпараметър

• Невалидно състояние на файл, поток или друг Невалидно състояние на файл, поток или друг манипулатор на ресурсманипулатор на ресурс

• Излизане извън размера на масив или колекцияИзлизане извън размера на масив или колекция

Page 32: Nakov High Quality Code

Assertions – Assertions – препоръкипрепоръки

• Използвайте изключения или друг механизъм Използвайте изключения или друг механизъм за контрол на очакваните грешкиза контрол на очакваните грешки

• Използвайте assertions само за грешки, които Използвайте assertions само за грешки, които никога не трябва да се случватникога не трябва да се случват

• Не слагайте изпълним код в assertionНе слагайте изпълним код в assertion• Лош пример: Лош пример: assert(ConnectToDatabase(), assert(ConnectToDatabase(), "Can not establish database connection!")"Can not establish database connection!")

• Използвайте Използвайте assertions assertions за да документирате за да документирате входни и изходни условия в методитевходни и изходни условия в методите

• Добавете код за управление на грешката след Добавете код за управление на грешката след assertionassertion (за по-голяма надеждност) (за по-голяма надеждност)

Page 33: Nakov High Quality Code

Изключения (Изключения (exceptionsexceptions))

• Изключенията (Изключенията (exceptionsexceptions) предоставят мощен ) предоставят мощен механизъм за централизирано управление на механизъм за централизирано управление на грешки и непредвидени ситуациигрешки и непредвидени ситуации

• Позволяват проблемните ситуации да се Позволяват проблемните ситуации да се обработват на много ниваобработват на много нива

• Улесняват писането и поддръжката на Улесняват писането и поддръжката на надежден програмен коднадежден програмен код

• Изключенията могат да бъдат класове – да се Изключенията могат да бъдат класове – да се наследяват и да образуват йерархиинаследяват и да образуват йерархии

• Могат да се използват на мястото на Могат да се използват на мястото на assertionsassertions

Page 34: Nakov High Quality Code

Изключения – препоръкиИзключения – препоръки

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

• Хвърляйте изключение само в ситуации, които Хвърляйте изключение само в ситуации, които наистина са изключителни и трябва да се наистина са изключителни и трябва да се обработят по някакъв начинобработят по някакъв начин

• Ако даден проблем може да се обработи локално, Ако даден проблем може да се обработи локално, направете го и не хвърляйте изключениенаправете го и не хвърляйте изключение

• Хвърляйте изключенията на подходящо ниво на Хвърляйте изключенията на подходящо ниво на абстракцияабстракция

• Пример: Пример: GetEmplyeeInfo()GetEmplyeeInfo() може да хвърля може да хвърля EmployeeExceptionEmployeeException, но не и , но не и FileNotFoundExceptionFileNotFoundException

Page 35: Nakov High Quality Code

Изключения – препоръкиИзключения – препоръки

• Включвайте в съобщението на изключението Включвайте в съобщението на изключението пълно описание на причината за възникването мупълно описание на причината за възникването му

• Всеки Всеки catch catch блок трябва да прихваща само блок трябва да прихваща само изключенията, които очаква и знае как да изключенията, които очаква и знае как да обработва, а не всичкиобработва, а не всички

• Catch Catch блоковете трябва да са подредени така, че блоковете трябва да са подредени така, че да започват от изключенията най-ниско в да започват от изключенията най-ниско в йерархията и да продължават с по-общитейерархията и да продължават с по-общите

• Избягвайте празни Избягвайте празни catch catch блоковеблокове

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

Page 36: Nakov High Quality Code

Изключения – препоръкиИзключения – препоръки

• Очаквайте описаните в документацията Очаквайте описаните в документацията изключенияизключения

• Документирайте изключенията, които вашият код Документирайте изключенията, които вашият код може да предизвикаможе да предизвика

• Управлявайте всички необработени изключения Управлявайте всички необработени изключения централизираноцентрализирано

• Можете да покажете съобщение за проблем на Можете да покажете съобщение за проблем на потребителя и да запишете проблема в потребителя и да запишете проблема в log log файлфайл

• Установете стандарти за изключенията в Установете стандарти за изключенията в приложението и дефинирайте класова йерархияприложението и дефинирайте класова йерархия

• Хвърляйте само обекти от тип "изключение" или Хвърляйте само обекти от тип "изключение" или негови наследници, а не указатели и числанегови наследници, а не указатели и числа

Page 37: Nakov High Quality Code

Колко защитно програмиране да Колко защитно програмиране да оставим в оставим в Release Release версиятаверсията

• Оставете кода, който проверява за важни грешкиОставете кода, който проверява за важни грешки

• Премахнете кода, който проверява за маловажни Премахнете кода, който проверява за маловажни грешкигрешки

• Премахнете кода, който предизвиква Премахнете кода, който предизвиква непосредствени сривовенепосредствени сривове

• Заместете го с код, който прекратява програмата Заместете го с код, който прекратява програмата "културно", без загуба на данни"културно", без загуба на данни

• Непременно Непременно log-log-вайте грешките при клиентавайте грешките при клиента

• Ако показвате съобщения за проблеми на Ако показвате съобщения за проблеми на потребителя, съобразете се с неговите знанияпотребителя, съобразете се с неговите знания

Page 38: Nakov High Quality Code

Как да използваме Как да използваме променливите?променливите?

Качествен програмен кодКачествен програмен код

Page 39: Nakov High Quality Code

Принципи при инициализиранеПринципи при инициализиране

• Проблемите:Проблемите:

• Неинициализирана променливаНеинициализирана променлива

• Пример: Пример: int value;int value;

• Частично инициализирана променливаЧастично инициализирана променлива

• Пример:Пример:

Student student = new Student();Student student = new Student();

Student.Name = "Бай Мангал";Student.Name = "Бай Мангал";

// Student.Age – не е инициализирано// Student.Age – не е инициализирано

Page 40: Nakov High Quality Code

• Инициализирайте променливите в момента на Инициализирайте променливите в момента на деклариране деклариране

• Инициализирайте всяка променлива близо до Инициализирайте всяка променлива близо до мястото където се използва за пръв пътмястото където се използва за пръв път

• Обръщайте специално внимание на Обръщайте специално внимание на променливите за броене и натрупванепроменливите за броене и натрупване

• Инициализирайте член-променливите на един Инициализирайте член-променливите на един клас в конструктораклас в конструктора

Принципи при инициализиранеПринципи при инициализиране

Page 41: Nakov High Quality Code

• Използвайте настройките на компилатора за Използвайте настройките на компилатора за автоматично инициализиране на променливитеавтоматично инициализиране на променливите

• Включвайте предупредителните съобщения от Включвайте предупредителните съобщения от компилаторакомпилатора

• Проверявайте входните параметри за Проверявайте входните параметри за валидноствалидност

• Проверявайте за невалидни указатели към Проверявайте за невалидни указатели към паметтапаметта

• Инициализирайте работната памет в началото Инициализирайте работната памет в началото на програматана програмата

Принципи при инициализиранеПринципи при инициализиране

Page 42: Nakov High Quality Code

Обхват, живот, активностОбхват, живот, активност

• Обхват (Обхват (variable scope)variable scope) – колко “известна” е една – колко “известна” е една променливапроменлива

• Глобална (статична), член-променлива, локалнаГлобална (статична), член-променлива, локална

• Диапазон на активностДиапазон на активност (span) (span) – среден брой линии – среден брой линии между обръщенията към даден променливамежду обръщенията към даден променлива

• Живот (Живот (lifetimelifetime) – обем на кода от първото до ) – обем на кода от първото до последното рефериране в даден методпоследното рефериране в даден метод

• Проследете къде се използва дадена променливаПроследете къде се използва дадена променлива, , нейният диапазон на активност и период на животнейният диапазон на активност и период на живот

• Направете обхвата, живота и активността на Направете обхвата, живота и активността на променливите колкото се може по-малкипроменливите колкото се може по-малки

Page 43: Nakov High Quality Code

Работа с променливиРабота с променливи

• Инициализирайте променливите извън тялото на Инициализирайте променливите извън тялото на цикълацикъла

• Не инициализирайте променлива до момента, в Не инициализирайте променлива до момента, в който ще бъде използванакойто ще бъде използвана

• Групирайте сходните операцииГрупирайте сходните операции

• Започнете с най-малкия обхват и разширявайте, Започнете с най-малкия обхват и разширявайте, ако се наложиако се наложи

• Използвайте всяка променлива точно и само за Използвайте всяка променлива точно и само за една целедна цел

• Избягвайте променливи със скрито значениеИзбягвайте променливи със скрито значение

• Използвайте всички декларирани променливиИзползвайте всички декларирани променливи

Page 44: Nakov High Quality Code

Почивка!Почивка!

Качествен програмен кодКачествен програмен код

Page 45: Nakov High Quality Code

Как да именуваме Как да именуваме променливите?променливите?

Качествен програмен кодКачествен програмен код

Page 46: Nakov High Quality Code

Именуване на променливиИменуване на променливи

• Избирайте добро име!Избирайте добро име!

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

• Добри имена: Добри имена: accountaccount, , blockSizeblockSize, , customerDiscountcustomerDiscount

• Лоши имена: Лоши имена: r18pqr18pq, , __hip__hip, , rcfdrcfd, , val1val1, , val2val2

• Адресирайте проблема, който решава Адресирайте проблема, който решава променливата – “какво” вместо “как”променливата – “какво” вместо “как”

• Добри имена: Добри имена: employeeSalaryemployeeSalary, , employeesemployees

• Лоши имена: Лоши имена: myArraymyArray, , customerFilecustomerFile, , customerHashTablecustomerHashTable

Page 47: Nakov High Quality Code

Именуване на променливиИменуване на променливи

• Оптимална дължина на името – 10 до 16 символаОптимална дължина на името – 10 до 16 символа

• Изборът на име зависи от обхватаИзборът на име зависи от обхвата• Променливите с по-голям обхват и по-дълъг живот имат Променливите с по-голям обхват и по-дълъг живот имат

по-дълго и описателно име:по-дълго и описателно име:

protected Account[] mCustomerAccounts;protected Account[] mCustomerAccounts;

• Променливите с малък обхват и кратък живот могат да Променливите с малък обхват и кратък живот могат да са по-кратки:са по-кратки:

for (int i=0; i<customers.Length; i++) { … }for (int i=0; i<customers.Length; i++) { … }

• Използвайте пространства за избягване на Използвайте пространства за избягване на повторения при декларирането:повторения при декларирането:

System.Windows.Forms.TextBoxSystem.Windows.Forms.TextBox

System.Web.UI.System.Web.UI.WebWebControls.TextBoxControls.TextBox

Page 48: Nakov High Quality Code

Именуване на специфични Именуване на специфични типове даннитипове данни

• Именуване на броячиИменуване на броячи• Пример: Пример: UsersCountUsersCount, , RolesCountRolesCount, , FilesCountFilesCount

• Именуване на променливи за състояниеИменуване на променливи за състояние• Пример: Пример: ThreadStateThreadState, , TransactionStateTransactionState

• Именуване на временни променливиИменуване на временни променливи• Пример: Пример: indexindex, , valuevalue, , countcount

• Лош пример: Лош пример: aa, , aaaa, , tmpvar1tmpvar1, , tmpvar2tmpvar2

• При булеви променливи използвайте имена, При булеви променливи използвайте имена, които дават предпоставка за истина или лъжакоито дават предпоставка за истина или лъжа• Пример: Пример: canReadcanRead, , availableavailable, , isOpenisOpen, , validvalid

Page 49: Nakov High Quality Code

Именуване на специфични Именуване на специфични типове даннитипове данни

• Булевите променливи трябва да носят "истина" Булевите променливи трябва да носят "истина" в името сив името си• Пример: Пример: isReadyisReady, , canReadcanRead, , hasMoreDatahasMoreData

• Лош пример: Лош пример: notReadynotReady, , cannotReadcannotRead, , noMoreDatanoMoreData

• Именуване на изброими типовеИменуване на изброими типове• Използвайте вградените изброени типове (когато Използвайте вградените изброени типове (когато

езикът за програмиране ги поддържа):езикът за програмиране ги поддържа):Color.RedColor.Red, , Color.YellowColor.Yellow, , Color.BlueColor.Blue

• Или използвайте подходящи префикси:Или използвайте подходящи префикси:colorRedcolorRed, , colorBluecolorBlue, , colorYellowcolorYellow

• Именуване на константи – с главни буквиИменуване на константи – с главни букви• Пример: Пример: MAX_FORM_WIDTHMAX_FORM_WIDTH, , BUFFER_SIZEBUFFER_SIZE

Page 50: Nakov High Quality Code

Кога е необходима конвенция за Кога е необходима конвенция за именуванеименуване

• Когато екипът е по-голямКогато екипът е по-голям

• Когато програмата ще се поддържа дълго времеКогато програмата ще се поддържа дълго време

• Когато програмата ще се проверява от други Когато програмата ще се проверява от други програмисти във Вашата организацияпрограмисти във Вашата организация

• Когато програмата е прекалено голяма и е Когато програмата е прекалено голяма и е невъзможно да се проследят всички модули невъзможно да се проследят всички модули наведнъжнаведнъж

• Когато програмата ще спре да се развива за Когато програмата ще спре да се развива за известно времеизвестно време

• Когато във вашия проект имате много непозната Когато във вашия проект имате много непозната терминология, обща за целия проекттерминология, обща за целия проект

Page 51: Nakov High Quality Code

Стандартни префиксиСтандартни префикси

• Унгарска конвенция – използва се все по-рядкоУнгарска конвенция – използва се все по-рядко

• Дефинирани типове от потребителяДефинирани типове от потребителя

• Например: Например: typedef int Color;typedef int Color;

• Семантични префикси (напр. Семантични префикси (напр. btnSavebtnSave))

• Не изпускайте букви за да съкратите иметоНе изпускайте букви за да съкратите името

• Съкращавайте по един и същ начин из целия кодСъкращавайте по един и същ начин из целия код

• Създавайте имена, които да можете да Създавайте имена, които да можете да произнесете (не като произнесете (не като btnDfltSvRzltsbtnDfltSvRzlts))

• Избягвайте комбинации, които водят до друга Избягвайте комбинации, които водят до друга дума или различно значениедума или различно значение ( (напр. напр. preFixStorepreFixStore))

Page 52: Nakov High Quality Code

Стандартни префиксиСтандартни префикси

• Документирайте кратките имена в кодаДокументирайте кратките имена в кода

• Помнете, че имената са предназначени за хората, Помнете, че имената са предназначени за хората, които ще четат кода, а не за тези които го пишаткоито ще четат кода, а не за тези които го пишат

• Избягвайте заблуждаващи имена или съкращенияИзбягвайте заблуждаващи имена или съкращения

• Избягвайте променливи с подобни имена, но с Избягвайте променливи с подобни имена, но с различно предназначениеразлично предназначение

• Например: Например: UserStatusUserStatus и и UserUserCurrentCurrentStatusStatus

• Избягвайте имена, които звучат еднаквоИзбягвайте имена, които звучат еднакво

• Избягвайте цифри в именатаИзбягвайте цифри в имената ( (напр. напр. pi314pi314))

• Избягвайте грешно написани думи в именатаИзбягвайте грешно написани думи в имената

Page 53: Nakov High Quality Code

Стандартни префиксиСтандартни префикси

• Избягвайте думи, които често се грешатИзбягвайте думи, които често се грешат

• Избягвайте използването на повече от един Избягвайте използването на повече от един народен езикнароден език

• Избягвайте използването на стандартни Избягвайте използването на стандартни типове и ключови думи в имената на типове и ключови думи в имената на променливитепроменливите

• Не използвайте имена, които нямат нищо общо Не използвайте имена, които нямат нищо общо с това което променливите съдържатс това което променливите съдържат

• Избягвайте имена, които съдържат трудни за Избягвайте имена, които съдържат трудни за четене символичетене символи

Page 54: Nakov High Quality Code

Какво е преработка на Какво е преработка на кода (кода (RefactoringRefactoring)?)?

Качествен програмен кодКачествен програмен код

Page 55: Nakov High Quality Code

Митове и реалност за процеса Митове и реалност за процеса за разработка на софтуерза разработка на софтуер

• МитътМитът

• Когато един проект стриктно спазва Когато един проект стриктно спазва правилата на процеса за разработка, правилата на процеса за разработка, единствената последвала промяна в кода е единствената последвала промяна в кода е само в периода на поддръжка на софтуера само в периода на поддръжка на софтуера ((software maintenance phase)software maintenance phase)

• Така генерирането на код е праволинейно Така генерирането на код е праволинейно без да се налага преработка без да се налага преработка

Page 56: Nakov High Quality Code

Митове и реалност за процеса Митове и реалност за процеса за разработка на софтуерза разработка на софтуер

• РеалносттаРеалността

• Кодът постоянно се променяКодът постоянно се променя

• Причината: променя се разбирането за Причината: променя се разбирането за проблемната област в хода развитие на проектапроблемната област в хода развитие на проекта

• Всяка промяна в изискванията налага Всяка промяна в изискванията налага промени и в съществуващия кодпромени и в съществуващия код

• Дори в най-добре управляваните проектиДори в най-добре управляваните проекти

Page 57: Nakov High Quality Code

Преработка на кода (Преработка на кода (Refactoring)Refactoring)

• Еволюцията на софтуера наподобява Еволюцията на софтуера наподобява биологичната еволюциябиологичната еволюция

• Някои промени са с благоприятен ефект, Някои промени са с благоприятен ефект, други не садруги не са

• Еволюцията на софтуера е неизбежнаЕволюцията на софтуера е неизбежна

• Еволюцията е възможност да се Еволюцията е възможност да се приближим към “съвършения” продуктприближим към “съвършения” продукт

Page 58: Nakov High Quality Code

Преработка на кода (Преработка на кода (Refactoring)Refactoring)

• Основно правило на еволюцията на софтуера:Основно правило на еволюцията на софтуера:

Еволюцията трябва да подобрява Еволюцията трябва да подобрява начина на реализация на даден проектначина на реализация на даден проект

• Основният начин за реализиране на това Основният начин за реализиране на това правило:правило:

Преработката на кодаПреработката на кода

Page 59: Nakov High Quality Code

Кога даден код се нуждае от Кога даден код се нуждае от преработка ?преработка ?

• Повторение на кодПовторение на код

• При проблеми в дублициран код се налага да се При проблеми в дублициран код се налага да се правят модификации на няколко местаправят модификации на няколко места

• Даден метод е прекалено обемистДаден метод е прекалено обемист

• Даден цикъл е прекалено обемист или Даден цикъл е прекалено обемист или съдържа дълбоко ниво на влаганесъдържа дълбоко ниво на влагане

• Даден клас изпълнява несвързани Даден клас изпълнява несвързани отговорности (отговорности (poor cohesion)poor cohesion)

• Даден клас не предоставя добро ниво на Даден клас не предоставя добро ниво на абстракцияабстракция

Page 60: Nakov High Quality Code

Кога даден код се нуждае от Кога даден код се нуждае от преработка ? (продължение)преработка ? (продължение)

• Даден метод има дълъг списък с параметриДаден метод има дълъг списък с параметри

• Една промяна налага паралелна модификация Една промяна налага паралелна модификация на няколко класана няколко класа

• Свързани една с друга данни се използват Свързани една с друга данни се използват винаги заедно, но не са обединени в класвинаги заедно, но не са обединени в клас

• Даден метод използва повече функционалност Даден метод използва повече функционалност от други класове отколкото от собствения сиот други класове отколкото от собствения си

• Даден клас е прекалено обвързан с другДаден клас е прекалено обвързан с друг

• Полета на даден клас са Полета на даден клас са publicpublic

Page 61: Nakov High Quality Code

Преработка на код на ниво Преработка на код на ниво данниданни

• Заместете “вълшебните” числа и низове с Заместете “вълшебните” числа и низове с именувана константа (напр. именувана константа (напр. 10241024 BUF_SIZEBUF_SIZE))

• Преименувайте дадена променлива с по-ясно Преименувайте дадена променлива с по-ясно и по-информативно име (и по-информативно име (pp currentPoscurrentPos))

• Преработете даден условен израз в методПреработете даден условен израз в метод

• Използвайте междинни променливи за Използвайте междинни променливи за резултата от сложни изразирезултата от сложни изрази

• Преобразувайте обикновени данни в нов класПреобразувайте обикновени данни в нов клас

• Групирайте свързаните константи в изброими Групирайте свързаните константи в изброими типове (enumerations)типове (enumerations)

Page 62: Nakov High Quality Code

Преработка на кода на ниво Преработка на кода на ниво методметод

• Преметете фрагмент от кода на даден Преметете фрагмент от кода на даден метод в нов методметод в нов метод (extract method) (extract method)

• Премахнете даден метод, ако кодът, който Премахнете даден метод, ако кодът, който съдържа, е прекалено прост и кратъксъдържа, е прекалено прост и кратък

• Преработете дълъг и сложен метод в Преработете дълъг и сложен метод в няколко по-малки или в изцяло нов класняколко по-малки или в изцяло нов клас

• Премахнете неизползваните параметриПремахнете неизползваните параметри

• Ако има нужда от допълнителен параметър Ако има нужда от допълнителен параметър за даден метод, добавете гоза даден метод, добавете го

Page 63: Nakov High Quality Code

Преработка на кода на ниво Преработка на кода на ниво класклас

• Променете обекти, подавани по стойност, с Променете обекти, подавани по стойност, с обекти, подавани по указател (референция)обекти, подавани по указател (референция)

• Изнесете общата функционалност за набор Изнесете общата функционалност за набор от класове в отделен базов класот класове в отделен базов клас

• Преместете метод от един клас в друг, ако Преместете метод от един клас в друг, ако той логически принадлежи на последниятой логически принадлежи на последния

• Преобразувайте един клас в два или повечеПреобразувайте един клас в два или повече

• Премахнете даден клас, ако не се ползваПремахнете даден клас, ако не се ползва

Page 64: Nakov High Quality Code

Преработка на кода на ниво Преработка на кода на ниво системасистема

• Създайте абстракция на данните, върху които Създайте абстракция на данните, върху които нямате контролнямате контрол

• Дефинирайте клас, който ще енкапсулира тези данни Дефинирайте клас, който ще енкапсулира тези данни и чиито обекти ще бъдат подавани на потребителитеи чиито обекти ще бъдат подавани на потребителите

• Ако не е наложително, премахвайте цикличните Ако не е наложително, премахвайте цикличните зависимости между класоветезависимости между класовете

• Ако не е нужна употребата на изключения, Ако не е нужна употребата на изключения, използвайте кодове за грешкиизползвайте кодове за грешки

• Използвайте "Използвайте "factoryfactory метод" за създаване на метод" за създаване на инстанции на даден клас според даден параметъринстанции на даден клас според даден параметър

Page 65: Nakov High Quality Code

Какво е Какво е самодокументиращ се самодокументиращ се

код и как се реализира?код и как се реализира?

Качествен програмен кодКачествен програмен код

Page 66: Nakov High Quality Code

Стилът на програмиране и Стилът на програмиране и документациятадокументацията

• Документация на високо нивоДокументация на високо ниво• Архитектурен план на систематаАрхитектурен план на системата

• Документация на ниско нивоДокументация на ниско ниво• Разглежда особености в най-големи детайли, Разглежда особености в най-големи детайли,

касаещи кода на програматакасаещи кода на програмата

• Коментарите в кода не са основният източник Коментарите в кода не са основният източник на документацияна документация• Добрият стил на програмиране е най-добрата Добрият стил на програмиране е най-добрата

документация!документация!

• Самодокументиращ се кодСамодокументиращ се код• Лесно се разбира основната му целЛесно се разбира основната му цел

Page 67: Nakov High Quality Code

Характеристики на Характеристики на самодокументиращия се кодсамодокументиращия се код

• Добра структура на програмата – Добра структура на програмата – подравняване, организация на кодаподравняване, организация на кода

• Използване на ясни и лесни за разбиране Използване на ясни и лесни за разбиране конструкцииконструкции

• Употреба на подходящи имена на променливи, Употреба на подходящи имена на променливи, методи и класовеметоди и класове

• Употреба на именувани константи, вместо Употреба на именувани константи, вместо “магически” константи и стрингове“магически” константи и стрингове

• Минимизация на сложността на реализациятаМинимизация на сложността на реализацията

Page 68: Nakov High Quality Code

Самодокументиращ се код – Самодокументиращ се код – важни въпросиважни въпроси

• Дава ли интерфейсът на класа добра абстракция?Дава ли интерфейсът на класа добра абстракция?

• Подходящо ли е името на класа и показва ли Подходящо ли е името на класа и показва ли основната му цел?основната му цел?

• Става ли ясно от интерфейса как трябва да се Става ли ясно от интерфейса как трябва да се използва класа?използва класа?

• Показва ли името на метода основната му цел?Показва ли името на метода основната му цел?

• Всеки метод реализира ли една добре определена Всеки метод реализира ли една добре определена задача?задача?

• Имената на променливите съответстват ли на Имената на променливите съответстват ли на тяхната употреба?тяхната употреба?

Page 69: Nakov High Quality Code

Самодокументиращ се код – Самодокументиращ се код – важни въпроси (продължение)важни въпроси (продължение)

• Групирани ли са свързаните един с друг Групирани ли са свързаните един с друг оператори?оператори?

• Само една задача ли изпълняват Само една задача ли изпълняват конструкциите за итерация (циклите)?конструкциите за итерация (циклите)?

• Има ли дълбоко влагане на условни клаузи?Има ли дълбоко влагане на условни клаузи?

• Показва ли организацията на кода неговата Показва ли организацията на кода неговата логическата структура?логическата структура?

• Дизайнът недвусмислен и ясен ли е?Дизайнът недвусмислен и ясен ли е?

• Скрити ли са детайлите на имплементацията Скрити ли са детайлите на имплементацията възможно най-много?възможно най-много?

Page 70: Nakov High Quality Code

““Ефективни” коментари Ефективни” коментари

• Коментарите понякога могат да навредят Коментарите понякога могат да навредят повече отколкото да помогнатповече отколкото да помогнат

• Добрите коментари не повтарят кода и не го Добрите коментари не повтарят кода и не го обясняват – те изясняват неговата идеяобясняват – те изясняват неговата идея

• Коментарите трябва да обясняват на по-високо Коментарите трябва да обясняват на по-високо ниво какво се опитваме да постигнемниво какво се опитваме да постигнем

• Писането на коментари помага да осмислим Писането на коментари помага да осмислим по-добре това, което искаме да реализирамепо-добре това, което искаме да реализираме

Page 71: Nakov High Quality Code

Правила на “ефективните” Правила на “ефективните” коментарикоментари

• Използвайте псевдокод, когато е възможноИзползвайте псевдокод, когато е възможно

• Пишете коментари когато създавате самия Пишете коментари когато създавате самия код, а не след товакод, а не след това

• Продуктивността не е добра причина за да не Продуктивността не е добра причина за да не пишете коментарипишете коментари

• Документирайте всичко, което не става ясно от Документирайте всичко, което не става ясно от вашия кодвашия код

• Поставянето на много коментари е толкова Поставянето на много коментари е толкова вредно колкото и липсата на такивавредно колкото и липсата на такива

• Не коментирайте трудно разбираем код – по Не коментирайте трудно разбираем код – по добре го преработетедобре го преработете

Page 72: Nakov High Quality Code

Ресурси по тематаРесурси по темата

Code Complete, 2Code Complete, 2ndnd edition, Steve edition, Steve McConnell, Microsoft Press, 2004, McConnell, Microsoft Press, 2004, ISBN ISBN 07356196700735619670, , http://www.cc2e.com/

• Курс по "Качествен програмен код"Курс по "Качествен програмен код" в СУ –в СУ – http://www.devbg.org/codecourse/

Page 73: Nakov High Quality Code

Качествен програмен кодКачествен програмен код

Въпроси?Въпроси?