54
Практические советы по улучшению качества кода

практические советы по улучшению качества кода

Embed Size (px)

Citation preview

Page 1: практические советы по улучшению качества кода

Практические советы по улучшению качества кода

Page 2: практические советы по улучшению качества кода

О себе• PHP разработчик более 5 лет

• Работа в компаниях

• СертификатыАфанасьев Юрий [email protected]

Page 3: практические советы по улучшению качества кода

Почему важна читаемость?• Чтение кода происходит чаще, нежели чем его написание

• Чем проще читать код, тем легче его сопровождать и находить в нём баги

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

3

Page 4: практические советы по улучшению качества кода

Что делает этот код?

function calculate() {

return (hours + overtime * rate) * days * gradeRate

}

4

Page 5: практические советы по улучшению качества кода

Бывает и хуже…

function result() {

return (hrs + plus_time * rate) * number * level

}

5

Page 6: практические советы по улучшению качества кода

Плохо оформленный код• Неприятно изучать и читать

• В нём сложно найти баги

• Возникают проблемы сопровождения и поддержки

• Его сложно дописывать, исправлять и что-либо с ним делать

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

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

6

Page 7: практические советы по улучшению качества кода

Стандарты кодирования• Java: Sun Microsystems

• Python: PEP-8

• PHP: PSR

• JavaScript: JSCS, Google Style Guide

7

Page 8: практические советы по улучшению качества кода

Пример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: практические советы по улучшению качества кода

Магические числа

Page 10: практические советы по улучшению качества кода

Магические числаЭто числа, такие как 100 или 32767, которые появляются в программе без объяснений

Строковые значения (например, ’creditcard’) могут также являться магическими числами

10

Page 11: практические советы по улучшению качества кода

Что здесь не так?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: практические советы по улучшению качества кода

float maxBooking = voyage.Capacity() * 1,1

const float OVERBOOKING = 1,1

float maxBooking = voyage.Capacity() * OVERBOOKING

12

Page 13: практические советы по улучшению качества кода

В чём удобство констант?• Улучшает понимание значения числа за счёт именованной константы

• Проще заменить значения таких чисел во всём коде

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

13

Page 14: практические советы по улучшению качества кода

ИсключениеЧисла исключения - 0 и 1 (если семантически означают начало отсчёта)

integer maxRange = 10000

for (n = 0; n < maxRange; ++n) {

// ....

}

14

Page 15: практические советы по улучшению качества кода

if (codeStatus == 403) {

const integer FORBIDDEN = 403

if (codeStatus == FORBIDDEN) {

15

Page 16: практические советы по улучшению качества кода

Методы в классах

Page 17: практические советы по улучшению качества кода

Что такое метод?Метод - это отдельная функция или процедура, выполняющая одну задачу

17

Page 18: практические советы по улучшению качества кода

Что здесь не так?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: практические советы по улучшению качества кода

float maxBooking = voyage.Capacity() * 1,1

if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {

if (

voyage.bookedCargoSize() + cargo.size() > this.getMaxBooking(voyage)

) {

19

Page 20: практические советы по улучшению качества кода

Цель методаМетод должен выполнять лишь одну четко определенную цель: запись в БД, выполнение сложных вычислений и т.д.

См. принципы SOLID (принцип одной ответственности SPR)

20

Page 21: практические советы по улучшению качества кода

function calculate (Cargo cargo, Voyage voyage) {

function isFull (Cargo cargo, Voyage voyage) {

21

Page 22: практические советы по улучшению качества кода

Именование методов• Описывайте все действия, происходящие в методе. Например, sendRequest(), computeRecordDetails()

• Избегайте побочных действий в методах!

• Метод должен выражать действие, поэтому первое слово всегда глагол. Например, getBankById(Id)

• Избегайте невыразительных имен. Например, handleOutput(), formatAndPrintOutput()

22

Page 23: практические советы по улучшению качества кода

Вложенность кода

Page 24: практические советы по улучшению качества кода

Что здесь не так?if (checkEmpty(message)) {

// … some code

if (maxValue < 100) {

// some code

if (foo->isValid()) {

// … save

} else {

logErrors();

}

}

}

24

Page 25: практические советы по улучшению качества кода

Проблема вложенности• Вложенность более 3-4 уровней сложно понять и удержать в голове

• Глубокая вложенность говорит о том, что код нужно рефакторить

25

Page 26: практические советы по улучшению качества кода

Как избавиться?• Переписать условия проверки if-else и циклов. Например, чаще использовать блок выхода (return)

• Разбить код на небольшие методы

26

Page 27: практические советы по улучшению качества кода

Перепишем пример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: практические советы по улучшению качества кода

В идеалеПишите код таким, чтобы он читался словно книга без постоянного перевода взгляда вверх и вниз страницы

28

Page 29: практические советы по улучшению качества кода

Комментарии

Page 30: практические советы по улучшению качества кода

Комментирование кода/* Убрано до лучших времён, которые вот-вот наступят

if (something) { return false } else { return true } */

GIT/SVN хранят историю изменений. Такие комментарии сродни мусору в квартире

30

Page 31: практические советы по улучшению качества кода

Волшебный TODO// TODO: упрощённая реализация алгоритма

// Отрефакторить в задаче ETC-1510

• Указывайте все недоработки сразу и заводите на них задачи

• Каждый такой комментарий указывает на недоработку (потенциальную уязвимость)

31

Page 32: практические советы по улучшению качества кода

Пояснения в начале файла/* @author Testof Tester Testorovich

@changes 01.01.2016 bug fix

@example new A() */

• В совместном проекте нет единого автора, т.к. каждый вносит свою лепту

• Историю изменений хранит git

• Пример использования может устареть

32

Page 33: практические советы по улучшению качества кода

Описание намерений// Проверка на загруженность транспортного средства

if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {

• Такой код чаще всего некачественный

• Комментарии часто устаревают

• Между комментарием и кодом может появиться другой код (!)

33

Page 34: практические советы по улучшению качества кода

Как избавиться?• Куски кода выделяйте в методы или классы if (voyage.bookedCargoSize() + cargo.size() > this.getMaxBooking(voyage)) {

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

const double OVERBOOKING = 1,1

float maxBooking = voyage.Capacity * OVERBOOKING

34

Page 35: практические советы по улучшению качества кода

Принцип DRYDon’t Repeat Yourself

Page 36: практические советы по улучшению качества кода

float maxBooking = voyage.Capacity() * 1,1

if (voyage.bookedCargoSize() + cargo.size() > maxBooking) {

if (

voyage.bookedCargoSize() + cargo.size() > this.getMaxBooking(voyage)

) {

36

Page 37: практические советы по улучшению качества кода

Один и только один разПовторяющиеся куски кода указывают на упущенную возможность для абстракции

Дублирующий код чаще выделяют в отдельный метод, реже - класс

37

Page 38: практические советы по улучшению качества кода

Де жа вю?• Куски кода выделяйте в методы или классы if (voyage.bookedCargoSize() + cargo.size() > this.getMaxBooking(voyage)) {

38

Page 39: практические советы по улучшению качества кода

Польза DRY• Другие разработчики могут воспользоваться вашим кодом и не выдумывать его самим

• Выделение абстракций повышает скорость разработки и уменьшает число ошибок

• Дублирующиеся части могут содержать различные реализации и разные ошибки

39

Page 40: практические советы по улучшению качества кода

Проблемаfunction findByName(name) { // …

sql = ‘SELECT * FROM bar WHERE name = ’ . name

// …

}

function findById (id) {

// … sql = ‘SELECT * FROM bar WHERE id = ’ . id

// …

}

40

Page 41: практические советы по улучшению качества кода

Решениеfunction findByName(name) { // …

sql = findBy(‘name’, name)

// …

}

function findById (id) {

// … sql = findBy(‘id’, id)

// …

}

41

Page 42: практические советы по улучшению качества кода

Ложка дёгтяСледование принципу неоправданно, если • Объединение реализаций плохо связанных сущностей (отзывы и комментарии)

• Код разных версий api

• В highload проектах (денормализация БД) • И так далее

Page 43: практические советы по улучшению качества кода

Принцип наименьшего удивления

Page 44: практические советы по улучшению качества кода

Что делает этот код?

date.add(5)

44

Page 45: практические советы по улучшению качества кода

Помните этот пример?

function result() {

return (hrs + plus_time * rate) * number * level

}

45

Page 46: практические советы по улучшению качества кода

Несколько правилПишите код так, чтобы он никого не удивлял

• Константы, методы должны располагаться на своём уровне абстракции

• Название метода должно соответствовать тому, что оно действительно выполняет

• Избавляйтесь от побочных эффектов в коде

46

Page 47: практические советы по улучшению качества кода

Выводы

Page 48: практические советы по улучшению качества кода

Код должен выражать намерения разработчика!

Магические числа, длинные и сложные выражения и т.д. - скрывают намерения автора

Page 49: практические советы по улучшению качества кода

И напоследок• В первую очередь, используйте стандарты, принятые в вашей компании

• Книги и статьи дают лишь рекомендации. Как использовать полученные знания решать вам

• Не переусердствуйте в своём желании улучшить мир кодом. Придерживайтесь золотой середины

49

Page 50: практические советы по улучшению качества кода

Книги и ссылки

Page 51: практические советы по улучшению качества кода

Совершенный код

Стив Макконнелл

Page 52: практические советы по улучшению качества кода

Чистый кодРоберт Мартин

Page 53: практические советы по улучшению качества кода

http://habrahabr.ru/post/266969/

http://geekbrains.ru/events/124

Ссылки

Page 54: практические советы по улучшению качества кода

Вопросы?