практические советы по улучшению качества кода
TRANSCRIPT
![Page 1: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/1.jpg)
Практические советы по улучшению качества кода
![Page 2: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/2.jpg)
О себе• PHP разработчик более 5 лет
• Работа в компаниях
• СертификатыАфанасьев Юрий [email protected]
![Page 3: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/3.jpg)
Почему важна читаемость?• Чтение кода происходит чаще, нежели чем его написание
• Чем проще читать код, тем легче его сопровождать и находить в нём баги
• Эстетическое восприятие влияет на многие показатели удобства работы с кодом и его поддержку
3
![Page 4: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/4.jpg)
Что делает этот код?
function calculate() {
return (hours + overtime * rate) * days * gradeRate
}
4
![Page 5: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/5.jpg)
Бывает и хуже…
function result() {
return (hrs + plus_time * rate) * number * level
}
5
![Page 6: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/6.jpg)
Плохо оформленный код• Неприятно изучать и читать
• В нём сложно найти баги
• Возникают проблемы сопровождения и поддержки
• Его сложно дописывать, исправлять и что-либо с ним делать
• Происходит постоянное наращивание кома никому непонятного кода
• В конечном виде код превращается в спагетти-код
6
![Page 7: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/7.jpg)
Стандарты кодирования• Java: Sun Microsystems
• Python: PEP-8
• PHP: PSR
• JavaScript: JSCS, Google Style Guide
7
![Page 8: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/8.jpg)
Примерclass Booking {
function calculate (Cargo cargo, Voyage voyage) {
float maxBooking = voyage.Capacity() * 1,1
if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {
return false
}
return true
}
}
8
![Page 9: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/9.jpg)
Магические числа
![Page 10: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/10.jpg)
Магические числаЭто числа, такие как 100 или 32767, которые появляются в программе без объяснений
Строковые значения (например, ’creditcard’) могут также являться магическими числами
10
![Page 11: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/11.jpg)
Что здесь не так?class Booking {
function calculate (Cargo cargo, Voyage voyage) {
float maxBooking = voyage.Capacity() * 1,1
if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {
return false
}
return true
}
}
11
![Page 12: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/12.jpg)
float maxBooking = voyage.Capacity() * 1,1
const float OVERBOOKING = 1,1
float maxBooking = voyage.Capacity() * OVERBOOKING
12
![Page 13: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/13.jpg)
В чём удобство констант?• Улучшает понимание значения числа за счёт именованной константы
• Проще заменить значения таких чисел во всём коде
• Код становится легко читаемым и понятным
13
![Page 14: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/14.jpg)
ИсключениеЧисла исключения - 0 и 1 (если семантически означают начало отсчёта)
integer maxRange = 10000
for (n = 0; n < maxRange; ++n) {
// ....
}
14
![Page 15: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/15.jpg)
if (codeStatus == 403) {
const integer FORBIDDEN = 403
if (codeStatus == FORBIDDEN) {
15
![Page 16: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/16.jpg)
Методы в классах
![Page 17: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/17.jpg)
Что такое метод?Метод - это отдельная функция или процедура, выполняющая одну задачу
17
![Page 18: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/18.jpg)
Что здесь не так?class Booking {
function calculate (Cargo cargo, Voyage voyage) {
float maxBooking = voyage.Capacity() * 1,1
if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {
return false
}
return true
}
}
18
![Page 19: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/19.jpg)
float maxBooking = voyage.Capacity() * 1,1
if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {
if (
voyage.bookedCargoSize() + cargo.size() > this.getMaxBooking(voyage)
) {
19
![Page 20: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/20.jpg)
Цель методаМетод должен выполнять лишь одну четко определенную цель: запись в БД, выполнение сложных вычислений и т.д.
См. принципы SOLID (принцип одной ответственности SPR)
20
![Page 21: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/21.jpg)
function calculate (Cargo cargo, Voyage voyage) {
function isFull (Cargo cargo, Voyage voyage) {
21
![Page 22: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/22.jpg)
Именование методов• Описывайте все действия, происходящие в методе. Например, sendRequest(), computeRecordDetails()
• Избегайте побочных действий в методах!
• Метод должен выражать действие, поэтому первое слово всегда глагол. Например, getBankById(Id)
• Избегайте невыразительных имен. Например, handleOutput(), formatAndPrintOutput()
22
![Page 23: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/23.jpg)
Вложенность кода
![Page 24: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/24.jpg)
Что здесь не так?if (checkEmpty(message)) {
// … some code
if (maxValue < 100) {
// some code
if (foo->isValid()) {
// … save
} else {
logErrors();
}
}
}
24
![Page 25: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/25.jpg)
Проблема вложенности• Вложенность более 3-4 уровней сложно понять и удержать в голове
• Глубокая вложенность говорит о том, что код нужно рефакторить
25
![Page 26: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/26.jpg)
Как избавиться?• Переписать условия проверки if-else и циклов. Например, чаще использовать блок выхода (return)
• Разбить код на небольшие методы
26
![Page 27: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/27.jpg)
Перепишем примерif ( !checkEmpty(message)) { return
}
// … some code if (maxValue > 100) {
return }
// … some code if (foo->isValid()) {
// … save
} else { logErrors();
}
if (checkEmpty(message)) {
// … some code
if (maxValue < 100) {
// some code
if (foo->isValid()) {
// … save
} else {
logErrors();
}
}
}
27
![Page 28: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/28.jpg)
В идеалеПишите код таким, чтобы он читался словно книга без постоянного перевода взгляда вверх и вниз страницы
28
![Page 29: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/29.jpg)
Комментарии
![Page 30: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/30.jpg)
Комментирование кода/* Убрано до лучших времён, которые вот-вот наступят
if (something) { return false } else { return true } */
GIT/SVN хранят историю изменений. Такие комментарии сродни мусору в квартире
30
![Page 31: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/31.jpg)
Волшебный TODO// TODO: упрощённая реализация алгоритма
// Отрефакторить в задаче ETC-1510
• Указывайте все недоработки сразу и заводите на них задачи
• Каждый такой комментарий указывает на недоработку (потенциальную уязвимость)
31
![Page 32: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/32.jpg)
Пояснения в начале файла/* @author Testof Tester Testorovich
@changes 01.01.2016 bug fix
@example new A() */
• В совместном проекте нет единого автора, т.к. каждый вносит свою лепту
• Историю изменений хранит git
• Пример использования может устареть
32
![Page 33: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/33.jpg)
Описание намерений// Проверка на загруженность транспортного средства
if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {
• Такой код чаще всего некачественный
• Комментарии часто устаревают
• Между комментарием и кодом может появиться другой код (!)
33
![Page 34: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/34.jpg)
Как избавиться?• Куски кода выделяйте в методы или классы if (voyage.bookedCargoSize() + cargo.size() > this.getMaxBooking(voyage)) {
• Строкам присваивайте пояснительные переменные или константы
const double OVERBOOKING = 1,1
float maxBooking = voyage.Capacity * OVERBOOKING
34
![Page 35: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/35.jpg)
Принцип DRYDon’t Repeat Yourself
![Page 36: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/36.jpg)
float maxBooking = voyage.Capacity() * 1,1
if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {
if (
voyage.bookedCargoSize() + cargo.size() > this.getMaxBooking(voyage)
) {
36
![Page 37: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/37.jpg)
Один и только один разПовторяющиеся куски кода указывают на упущенную возможность для абстракции
Дублирующий код чаще выделяют в отдельный метод, реже - класс
37
![Page 38: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/38.jpg)
Де жа вю?• Куски кода выделяйте в методы или классы if (voyage.bookedCargoSize() + cargo.size() > this.getMaxBooking(voyage)) {
38
![Page 39: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/39.jpg)
Польза DRY• Другие разработчики могут воспользоваться вашим кодом и не выдумывать его самим
• Выделение абстракций повышает скорость разработки и уменьшает число ошибок
• Дублирующиеся части могут содержать различные реализации и разные ошибки
39
![Page 40: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/40.jpg)
Проблемаfunction findByName(name) { // …
sql = ‘SELECT * FROM bar WHERE name = ’ . name
// …
}
function findById (id) {
// … sql = ‘SELECT * FROM bar WHERE id = ’ . id
// …
}
40
![Page 41: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/41.jpg)
Решениеfunction findByName(name) { // …
sql = findBy(‘name’, name)
// …
}
function findById (id) {
// … sql = findBy(‘id’, id)
// …
}
41
![Page 42: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/42.jpg)
Ложка дёгтяСледование принципу неоправданно, если • Объединение реализаций плохо связанных сущностей (отзывы и комментарии)
• Код разных версий api
• В highload проектах (денормализация БД) • И так далее
![Page 43: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/43.jpg)
Принцип наименьшего удивления
![Page 44: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/44.jpg)
Что делает этот код?
date.add(5)
44
![Page 45: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/45.jpg)
Помните этот пример?
function result() {
return (hrs + plus_time * rate) * number * level
}
45
![Page 46: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/46.jpg)
Несколько правилПишите код так, чтобы он никого не удивлял
• Константы, методы должны располагаться на своём уровне абстракции
• Название метода должно соответствовать тому, что оно действительно выполняет
• Избавляйтесь от побочных эффектов в коде
46
![Page 47: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/47.jpg)
Выводы
![Page 48: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/48.jpg)
Код должен выражать намерения разработчика!
Магические числа, длинные и сложные выражения и т.д. - скрывают намерения автора
![Page 49: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/49.jpg)
И напоследок• В первую очередь, используйте стандарты, принятые в вашей компании
• Книги и статьи дают лишь рекомендации. Как использовать полученные знания решать вам
• Не переусердствуйте в своём желании улучшить мир кодом. Придерживайтесь золотой середины
49
![Page 50: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/50.jpg)
Книги и ссылки
![Page 51: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/51.jpg)
Совершенный код
Стив Макконнелл
![Page 52: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/52.jpg)
Чистый кодРоберт Мартин
![Page 53: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/53.jpg)
http://habrahabr.ru/post/266969/
http://geekbrains.ru/events/124
Ссылки
![Page 54: практические советы по улучшению качества кода](https://reader033.vdocuments.pub/reader033/viewer/2022042618/58a828c31a28abbe408b4f9d/html5/thumbnails/54.jpg)
Вопросы?