high quality code introduction

Post on 27-Jun-2015

793 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

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

www.devbg.orgwww.devbg.org

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

База данни

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• Оптимална дължина на името – 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

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

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

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

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

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

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

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

• Булевите променливи трябва да носят "истина" Булевите променливи трябва да носят "истина" в името сив името си• Пример: Пример: 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

• МитътМитът

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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/

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

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

top related