Качествен програмен код презентация

Содержание

Лекторът Светлин Наков Директор на Национална академия по разработка на софтуер (НАРС) Безплатни курсове за програмисти – Java и .NET Обучение по стипендия + осигурена работа Председател на Българска асоциация на

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


Слайд 2Лекторът Светлин Наков
Директор на Национална академия по разработка на софтуер (НАРС)
Безплатни

курсове за програмисти – Java и .NET
Обучение по стипендия + осигурена работа
Председател на Българска асоциация на разработчиците на софтуер (БАРС)
Преподавател по съвременни софтуерни технологии в СУ "Св. Климент Охридски"
Консултант по разработка на софтуер
Носител на наградата "Джон Атанасов" на президента на България за 2004

Слайд 3Съдържание
Дефиниция за качествен код
Софтуерен дизайн
Висококачествени подпрограми
Защитно програмиране
Правилно използване на променливите
Имената на

променливите
Преработка на съществуващ код
Самодокументиращ се код

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


Слайд 5Какво е качествен код?
Качеството на софтуера има 2 аспекта:
Външно качество –

видимото за потребителя
Коректност на софтуера
Удобство и леснота за работа
Производителност (скорост на работа)
Вътрешно качество – вътрешната организация на архитектурата и програмния код
Разбираемост
Леснота за промяна и добавяне на функционалност (поддръжка)
Простота на реализацията

Слайд 6Какво е качествен код?
Характеристики за качество на кода:
Коректност
Четимост и разбираемост
Висока свързаност

на отговорностите (strong cohesion) на всички нива (модули, класове, методи)
Функционална независимост (loose coupling) на всички нива (модули, класове, методи)
Добро, консистентно форматиране
Подходящо и консистентно именуване на класовете, методите, променливите и останалите елементи
Добра документация, вградена в кода

Слайд 7Какво е качествен софтуерен дизайн?
Качествен програмен код


Слайд 8Софтуерен дизайн
Качеството на софтуера силно зависи от качеството на дизайна
Дизайнът е

трудно-дефинируем процес
Итеративен, недетерминистичен
Няма точна рецепта как да се прави
Основна цел на дизайна:
Да се управлява сложността на софтуера
Основен похват при дизайна:
Функционална декомпозиция на проблемите на всички нива

Слайд 9Какво е софтуерен дизайн
Софтуерният дизайн е:
Принципна организация на софтуерната система
Дизайнът се

състои от:
Архитектурен план
Описва основните компоненти и подсистеми на системата и взаимодействието между тях
Детайлен дизайн
Описва вътрешната организация на отделните компоненти и подсистеми
Описва класовете и методите в класовете

Слайд 10Характеристики на дизайна
Минимална сложност, леснота за разбиране
Леснота за поддръжка (промяна и

разширяване)
Функционална независимост между подсистемите, компонентите и класовете (loose coupling)
Преизползваемост (reusability)
Високa входна зависимост (fan-in)
Някои utility класове се използват много често
Ниска изходна зависимост (fan-out)
Един клас да не ползва прекалено много други класове
Минималност – да няма излишни части

Слайд 11Процесът на дизайн
Функционална декомпозиция:
Разделяме системата на подсистеми
Разделяме подсистемите на класове и

ги подреждаме в пакети (пространства от имена)
Разделяме класовете в подпрограми (методи)
Проектираме подпрограмите (чрез псевдокод)
Не е необходимо да се прави паралелно във всички посоки
Започва се от най-важната функционалност за клиента

Слайд 12Фази на дизайна
Разделяне на подсистемите на класове
Идентификация на обектите и процесите

от реалния свят
Съпоставяне на класове за тези обекти
Идентификация на връзките между обектите
Проектиране на класова йерархия
Използване на шаблони (design patterns)
Скриване на възможно най-много имплементационни детайли

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

обект може да извършва (методи)
Идентификация на съществените характеристики на обектите (атрибути)
Скриване на възможно най-много имплементационни детайли (private методи)
Максимална функционална независимост (loose coupling)
Висока свързаност на отговорностите (strong cohesion)

Слайд 14Фази на дизайна
Проектиране на вътрешността на методите
Най-често е отговорност на програмистите,

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

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


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


Слайд 17Защо да използваме методи?
Намаляваме сложността
Разбиваме сложните проблеми на по-прости
Добавяме междинни нива

на абстракция
Скриваме детайли за имплементацията
Намаляваме риска от неуспех
Избягваме повторението на еднакъв код
Скриваме сложни последователности от действия
Скриваме работата с указатели
Опростяваме сложни булеви проверки

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

методите
Генерален принцип: Един метод трябва да прави само едно нещо и да го прави добре
Операциите в един метод трябва да са взаимосвързани – насочени към обща задача
Идеалният случай:
Функционална кохезия
Методът извършва единична ясно дефинирана операция
Пример: функция Sqrt()

Слайд 19Допустими видове кохезия
Последователна кохезия
Редица от стъпки за решаване на единна задача
Пример:

SendEmail()
свързваме се към сървъра за поща
изпращаме съобщението
затваряме връзката
Комуникационна кохезия
Свързаност на действията по общи данни
Пример: DisplayReport()
извличаме данните
форматираме ги
отпечатваме ги

Слайд 20Допустими видове кохезия
Времева кохезия
Действия, които се извършват по едно и също

време
Пример: LoadSettings()
зареждаме настройките за шрифтовете
зареждаме настройките за цветовете
зареждаме настройките за принтера
зареждаме настройките за базата данни
зареждаме настройките за Интернет достъпа

Слайд 21Недопустими видове кохезия
Логическа кохезия
Изпълнява се различно действие според някой входен параметър

(код на операция)
Лош пример: ReadAll(int op_code) – прочита артикул, цена, адрес или ЕГН според подадения код
Изключение: Обработчици на събития (event handlers)
Случайна кохезия (липса на свързаност)
Няколко несвързани едно с друго действия
Изключително лоша практика!

Слайд 22Имената на методите
Името трябва да описва всичко, което методът извършва
Ако няма

подходящо име, имаме лоша кохезия!
Избягвайте безлични и общи думички
Лош пример: HandleStuff(), ProcessData()
Не използвайте цифри в името
Лош пример: ReadProfile1(), ReadProfile2()
Дължината на името трябва да е толкова дълга, колкото е необходимо (9-15 символа)
Ако името е прекалено дълго, имаме лоша кохезия
Използвайте английски език

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

на процедурите се съставят по схемата <глагол> + <обект>
Пример: PrintReport(), LoadSettings()
Използвайте консистентно противоположностите
Пример: OpenFile() и CloseFile()
Лош пример: OpenFile() и _descriptor_close()
Използвайте конвенция за честите операции
Пример: GetName(), GetAge(), SetName(), SetAge()
Спазвайте конвенцията навсякъде

Слайд 24Колко да са дълги методите?
Предпочитайте кратки методи (до един екран)
Методите трябва

да имат силна кохезия
Това е много по-важно от дължината им!
Методите трябва да са дълги "колкото трябва"
Не разделяйте на части даден метод само защото е много дълъг

Слайд 25Параметрите на методите
Подреждайте параметрите в последователност (, , )
Подреждайте консистентно параметрите

при методи с подобни параметри
Използвайте всички параметри
Ако връщате статус или код за грешка, сложете този параметър последен
Не използвайте параметрите като работни променливи (не модифицирайте параметрите)
Документирайте неочевидните допускания
Например мерната единица при подаване на числа

Слайд 26Параметрите на методите
Ограничете броя на параметрите до около 7
Човешкото съзнание не

може да следи повече от 7 неща едновременно (знаехте ли това?)
Разграничавайте входните от изходните параметри (ако езикът не го поддържа)
Кога да подаваме обект и кога няколко негови полета?
Съобразете се логически методът над какво работи – над обекти или над съвкупност от стойности
Подавайте параметрите в коректния им ред
Използвайте именувано извикване, ако се поддържа

Слайд 27Функция или процедура
Функция или процедура?
Използвайте функция когато основната задача на метода

е да изчисли и върне някаква стойност
Уверете се, че всеки път на изпълнение връща стойност
Не връщайте указател към локални данни
Запазете в променлива стойността преди да я върнете:
return days * hoursPerDay * ratePerHour;
int salary = days * hoursPerDay * ratePerHour;
return salary;



Слайд 28Какво е защитно програмиране?
Качествен програмен код


Слайд 29Защитно програмиране
Защитно програмиране (defensive programming)
Насочено към защита на кода от некоректни

данни
Пази кода от грешки, които никой не очаква
Имплементира се чрез проверка на коректността на всички входни данни
данните, идващи от външни източници
входните параметри на методите
Имплементира се чрез assertions, изключения и други средства за управление на грешки

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

неочаквани входни параметри или вътрешни състояния
Силно улесняват откриването на грешки в кода
Представляват изрази от вида:
assert(условие, съобщение_за_грешка)
Ако условието е нарушено, програмата завършва аварийно и се отпечатва грешката
При release компилация се премахват от кода
Много са полезни при големи и сложни проекти

Слайд 31Проверки (assertions)
Проверките на практика "документират" скритите допускания, които кодът очаква
Някои езици

поддържат assertions, в другите можем да си ги реализираме сами
Типични грешки, улавяни с assertions:
Стойност NULL на входен параметър
Стойност извън допустимия диапазон за входен параметър
Невалидно състояние на файл, поток или друг манипулатор на ресурс
Излизане извън размера на масив или колекция

Слайд 32Assertions – препоръки
Използвайте изключения или друг механизъм за контрол на очакваните

грешки
Използвайте assertions само за грешки, които никога не трябва да се случват
Не слагайте изпълним код в assertion
Лош пример: assert(ConnectToDatabase(), "Can not establish database connection!")
Използвайте assertions за да документирате входни и изходни условия в методите
Добавете код за управление на грешката след assertion (за по-голяма надеждност)

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

и непредвидени ситуации
Позволяват проблемните ситуации да се обработват на много нива
Улесняват писането и поддръжката на надежден програмен код
Изключенията могат да бъдат класове – да се наследяват и да образуват йерархии
Могат да се използват на мястото на assertions

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

за проблеми, които не трябва да бъдат игнорирани
Хвърляйте изключение само в ситуации, които наистина са изключителни и трябва да се обработят по някакъв начин
Ако даден проблем може да се обработи локално, направете го и не хвърляйте изключение
Хвърляйте изключенията на подходящо ниво на абстракция
Пример: GetEmplyeeInfo() може да хвърля EmployeeException, но не и FileNotFoundException

Слайд 35Изключения – препоръки
Включвайте в съобщението на изключението пълно описание на причината

за възникването му
Всеки catch блок трябва да прихваща само изключенията, които очаква и знае как да обработва, а не всички
Catch блоковете трябва да са подредени така, че да започват от изключенията най-ниско в йерархията и да продължават с по-общите
Избягвайте празни catch блокове
Не е правилно да прихващате всички изключения, без да ви интересува типа им

Слайд 36Изключения – препоръки
Очаквайте описаните в документацията изключения
Документирайте изключенията, които вашият код

може да предизвика
Управлявайте всички необработени изключения централизирано
Можете да покажете съобщение за проблем на потребителя и да запишете проблема в log файл
Установете стандарти за изключенията в приложението и дефинирайте класова йерархия
Хвърляйте само обекти от тип "изключение" или негови наследници, а не указатели и числа

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

за важни грешки
Премахнете кода, който проверява за маловажни грешки
Премахнете кода, който предизвиква непосредствени сривове
Заместете го с код, който прекратява програмата "културно", без загуба на данни
Непременно log-вайте грешките при клиента
Ако показвате съобщения за проблеми на потребителя, съобразете се с неговите знания

Слайд 38Как да използваме променливите?
Качествен програмен код


Слайд 39Принципи при инициализиране
Проблемите:
Неинициализирана променлива
Пример: int value;
Частично инициализирана променлива
Пример:
Student student = new

Student();
Student.Name = "Бай Мангал";
// Student.Age – не е инициализирано

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

мястото където се използва за пръв път
Обръщайте специално внимание на променливите за броене и натрупване
Инициализирайте член-променливите на един клас в конструктора

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


Слайд 41Използвайте настройките на компилатора за автоматично инициализиране на променливите
Включвайте предупредителните съобщения

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

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


Слайд 42Обхват, живот, активност
Обхват (variable scope) – колко “известна” е една променлива
Глобална

(статична), член-променлива, локална
Диапазон на активност (span) – среден брой линии между обръщенията към даден променлива
Живот (lifetime) – обем на кода от първото до последното рефериране в даден метод
Проследете къде се използва дадена променлива, нейният диапазон на активност и период на живот
Направете обхвата, живота и активността на променливите колкото се може по-малки

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

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

Слайд 44Почивка!
Качествен програмен код


Слайд 45Как да именуваме променливите?
Качествен програмен код


Слайд 46Именуване на променливи
Избирайте добро име!
Името трябва да описва точно и ясно

обекта, който променливата представлява
Добри имена: account, blockSize, customerDiscount
Лоши имена: r18pq, __hip, rcfd, val1, val2
Адресирайте проблема, който решава променливата – “какво” вместо “как”
Добри имена: employeeSalary, employees
Лоши имена: myArray, customerFile, customerHashTable

Слайд 47Именуване на променливи
Оптимална дължина на името – 10 до 16 символа
Изборът

на име зависи от обхвата
Променливите с по-голям обхват и по-дълъг живот имат по-дълго и описателно име:
protected Account[] mCustomerAccounts;
Променливите с малък обхват и кратък живот могат да са по-кратки:
for (int i=0; iИзползвайте пространства за избягване на повторения при декларирането:
System.Windows.Forms.TextBox
System.Web.UI.WebControls.TextBox

Слайд 48Именуване на специфични типове данни
Именуване на броячи
Пример: UsersCount, RolesCount, FilesCount
Именуване на

променливи за състояние
Пример: ThreadState, TransactionState
Именуване на временни променливи
Пример: index, value, count
Лош пример: a, aa, tmpvar1, tmpvar2
При булеви променливи използвайте имена, които дават предпоставка за истина или лъжа
Пример: canRead, available, isOpen, valid

Слайд 49Именуване на специфични типове данни
Булевите променливи трябва да носят "истина" в

името си
Пример: isReady, canRead, hasMoreData
Лош пример: notReady, cannotRead, noMoreData
Именуване на изброими типове
Използвайте вградените изброени типове (когато езикът за програмиране ги поддържа):
Color.Red, Color.Yellow, Color.Blue
Или използвайте подходящи префикси:
colorRed, colorBlue, colorYellow
Именуване на константи – с главни букви
Пример: MAX_FORM_WIDTH, BUFFER_SIZE

Слайд 50Кога е необходима конвенция за именуване
Когато екипът е по-голям
Когато програмата

ще се поддържа дълго време
Когато програмата ще се проверява от други програмисти във Вашата организация
Когато програмата е прекалено голяма и е невъзможно да се проследят всички модули наведнъж
Когато програмата ще спре да се развива за известно време
Когато във вашия проект имате много непозната терминология, обща за целия проект

Слайд 51Стандартни префикси
Унгарска конвенция – използва се все по-рядко
Дефинирани типове от потребителя
Например:

typedef int Color;
Семантични префикси (напр. btnSave)
Не изпускайте букви за да съкратите името
Съкращавайте по един и същ начин из целия код
Създавайте имена, които да можете да произнесете (не като btnDfltSvRzlts)
Избягвайте комбинации, които водят до друга дума или различно значение (напр. preFixStore)

Слайд 52Стандартни префикси
Документирайте кратките имена в кода
Помнете, че имената са предназначени за

хората, които ще четат кода, а не за тези които го пишат
Избягвайте заблуждаващи имена или съкращения
Избягвайте променливи с подобни имена, но с различно предназначение
Например: UserStatus и UserCurrentStatus
Избягвайте имена, които звучат еднакво
Избягвайте цифри в имената (напр. pi314)
Избягвайте грешно написани думи в имената

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

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

Слайд 54Какво е преработка на кода (Refactoring)?
Качествен програмен код


Слайд 55Митове и реалност за процеса за разработка на софтуер
Митът
Когато един проект

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

Слайд 56Митове и реалност за процеса за разработка на софтуер
Реалността
Кодът постоянно се

променя
Причината: променя се разбирането за проблемната област в хода развитие на проекта
Всяка промяна в изискванията налага промени и в съществуващия код
Дори в най-добре управляваните проекти

Слайд 57Преработка на кода (Refactoring)
Еволюцията на софтуера наподобява биологичната еволюция
Някои промени са

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

Слайд 58Преработка на кода (Refactoring)
Основно правило на еволюцията на софтуера:
Еволюцията трябва да

подобрява начина на реализация на даден проект
Основният начин за реализиране на това правило:
Преработката на кода

Слайд 59Кога даден код се нуждае от преработка ?
Повторение на код
При проблеми

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

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

дълъг списък с параметри
Една промяна налага паралелна модификация на няколко класа
Свързани една с друга данни се използват винаги заедно, но не са обединени в клас
Даден метод използва повече функционалност от други класове отколкото от собствения си
Даден клас е прекалено обвързан с друг
Полета на даден клас са public

Слайд 61Преработка на код на ниво данни
Заместете “вълшебните” числа и низове с

именувана константа (напр. 1024 → BUF_SIZE)
Преименувайте дадена променлива с по-ясно и по-информативно име (p → currentPos)
Преработете даден условен израз в метод
Използвайте междинни променливи за резултата от сложни изрази
Преобразувайте обикновени данни в нов клас
Групирайте свързаните константи в изброими типове (enumerations)

Слайд 62Преработка на кода на ниво метод
Преметете фрагмент от кода на даден

метод в нов метод (extract method)
Премахнете даден метод, ако кодът, който съдържа, е прекалено прост и кратък
Преработете дълъг и сложен метод в няколко по-малки или в изцяло нов клас
Премахнете неизползваните параметри
Ако има нужда от допълнителен параметър за даден метод, добавете го

Слайд 63Преработка на кода на ниво клас
Променете обекти, подавани по стойност, с

обекти, подавани по указател (референция)
Изнесете общата функционалност за набор от класове в отделен базов клас
Преместете метод от един клас в друг, ако той логически принадлежи на последния
Преобразувайте един клас в два или повече
Премахнете даден клас, ако не се ползва

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

нямате контрол
Дефинирайте клас, който ще енкапсулира тези данни и чиито обекти ще бъдат подавани на потребителите
Ако не е наложително, премахвайте цикличните зависимости между класовете
Ако не е нужна употребата на изключения, използвайте кодове за грешки
Използвайте "factory метод" за създаване на инстанции на даден клас според даден параметър

Слайд 65Какво е самодокументиращ се код и как се реализира?
Качествен програмен код


Слайд 66Стилът на програмиране и документацията
Документация на високо ниво
Архитектурен план на системата
Документация

на ниско ниво
Разглежда особености в най-големи детайли, касаещи кода на програмата
Коментарите в кода не са основният източник на документация
Добрият стил на програмиране е най-добрата документация!
Самодокументиращ се код
Лесно се разбира основната му цел

Слайд 67Характеристики на самодокументиращия се код
Добра структура на програмата – подравняване, организация

на кода
Използване на ясни и лесни за разбиране конструкции
Употреба на подходящи имена на променливи, методи и класове
Употреба на именувани константи, вместо “магически” константи и стрингове
Минимизация на сложността на реализацията

Слайд 68Самодокументиращ се код – важни въпроси
Дава ли интерфейсът на класа добра

абстракция?
Подходящо ли е името на класа и показва ли основната му цел?
Става ли ясно от интерфейса как трябва да се използва класа?
Показва ли името на метода основната му цел?
Всеки метод реализира ли една добре определена задача?
Имената на променливите съответстват ли на тяхната употреба?

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

с друг оператори?
Само една задача ли изпълняват конструкциите за итерация (циклите)?
Има ли дълбоко влагане на условни клаузи?
Показва ли организацията на кода неговата логическата структура?
Дизайнът недвусмислен и ясен ли е?
Скрити ли са детайлите на имплементацията възможно най-много?

Слайд 70“Ефективни” коментари
Коментарите понякога могат да навредят повече отколкото да помогнат
Добрите

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

Слайд 71Правила на “ефективните” коментари
Използвайте псевдокод, когато е възможно
Пишете коментари когато създавате

самия код, а не след това
Продуктивността не е добра причина за да не пишете коментари
Документирайте всичко, което не става ясно от вашия код
Поставянето на много коментари е толкова вредно колкото и липсата на такива
Не коментирайте трудно разбираем код – по добре го преработете

Слайд 72Ресурси по темата
Code Complete, 2nd edition, Steve McConnell, Microsoft Press, 2004,

ISBN 0735619670, http://www.cc2e.com/

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


Слайд 73Качествен програмен код
Въпроси?


Обратная связь

Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

Это сайт презентаций, докладов, проектов, шаблонов в формате PowerPoint. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами с другими пользователями.


Для правообладателей

Яндекс.Метрика