Как выжить, если вы начинаете первые шаги в программировании. Как не делать - не знаю как, но работает. Три секретных вопроса.
Вам что-то недоговаривают
Вот вы твердо решили, что хотите идти в сферу IT. Да не просто идти, а нырнуть туда с головой. И мечтаете стать высококлассным программистом. Уже посмотрели некоторые лекции, почитали какие-то уроки, возможно, даже купили пару книг. Но есть ощущение, что вам что-то не договаривают.
Повторяете то, что вам показывают в лекции или в статье. И, вроде, получается, даже в целом понятно как это работает. Но стоит попробовать сделать что-то похожее, и вы начинаете хромать и спотыкаться. Будто лепрекон сидит по ту сторону открытого вами редактора и тыкает палки в колеса вашего кода, злобно хихикая.
У лектора получается постепенно построить логику кода, но у вас - нет. Код пишется, но нить его логики от вас постоянно убегает, и в конце концов у вас получается нечто вроде "не знаю как, но работает".
Как этого избежать?
Раскрываем секрет
Программирование - это легко, поверьте. Для того, чтобы научиться программировать, нужно запомнить и всегда повторять всего три вопроса. Ответив на эти вопросы, вы всегда можете получить полное представление о написанном коде и разобраться что к чему.
Что же это за волшебные вопросы?
- Зачем эта часть кода, что она делает?
- Как можно управлять ее поведением?
- Что эта часть возвращает?
Вне зависимости от того, о чем идет речь: о большом модуле, о методе класса, о функции, о выражении, или даже о простом сложении, нужно и достаточно знать ответ только на эти три вопроса, чтобы полностью разобраться, что тут происходит.
Зачем эта часть кода, что она принципиально делает?
Чтобы ответить на вопрос о том, как работает код, нужно до мелочей знать весь процесс его работы? Нет, это не так, данный вопрос подразумевает кое-что другое.
Для того, чтобы ответить на него, вам не нужно вдаваться в детали, а просто взгляните на код в целом.
Смотрим на пример:
if ($cake->isVeryBig() && $cake->isCheaper(100)) {
echo 'Супер-скидка на торт';
}
Дробим его на части:
- Ага, это торт.
$cake
- А это мы узнаем большой он или нет.
$cake->isVeryBig()
- А это мы узнаем дешевле ли он ста загадочных монет.
$cake->isCheaper(100)
- А тут у нас условие. Чтобы его пройти, необходимо чтобы выполнились обе его части.
if (... && ...)
Переводим на человеческий язык: "если торт очень больший и он дешевле чем 100, выводим текст внутри этого условия."
Теперь мы знаем, что делает эта часть кода, а значит знаем ответ на вышеуказанный вопрос, хотя как код работает "там внутри" даже не догадываемся.
Как можно управлять ее поведением?
Переписать? Нет, это не управление поведением, но что-то мы можем здесь поменять, чтобы немного изменить поведение кода. Снова посмотрим на все его части:
- Торт как торт, тут мы ничего не можем поменять.
$cake
- Вряд ли метод принимает какие-то параметры, можно заглянуть внутрь него и узнать это точно, но думаю, что здесь мы тоже ничего не можем поменять. Скорее всего, когда мы делали торт, мы задавали размеры - там и поменяем при необходимости.
$cake->isVeryBig()
- Ага, 100, метод принимает параметр, значит мы можем управлять числом: дешевле чего должен быть торт, чтобы выполнилось условие.
$cake->isCheaper(100)
- А тут у нас условие, мы можем поменять "и" на "или".
if (... && ...)
Таким образом, мы можем управлять размерами торта, хотя и не в этой части кода. Ценой, ниже которой считаем, что торт со скидкой. При желании можем и условие поменять, доделать, расширить и т.д.
Что эта часть возвращает?
Если предыдущие вопросы более-менее понятны (скорее всего, вы ими уже задавались ранее, когда первый раз увидели код), то этот вопрос особенный.
Смотрим на код:
if ($cake->isVeryBig() && $cake->isCheaper(100)) {
echo 'Супер-скидка на торт';
}
Хотя, чего на него смотреть, он ничего не возвращает, а только проверяет условие и что-то выводит.
Но на этом останавливаться нельзя, и в этом как раз заключается особый секрет. Каждая строка, да что там строка - каждое слово, каждая операция, каждый вызов метода что-то возвращают. И если вы в каждой точке кода будете понимать, что здесь возвращается, то шагнете на ступень выше в своем мастерстве программирования.
Дробим пример и отвечаем на вопрос:
- Обращение к переменной возвращает ссылку на объект. Причем к этой переменной мы обращаемся в коде дважды.
$cake
- Этот метод возвращает true либо false.
$cake->isVeryBig()
- 100 - число возвращает число.
100
- Этот метод тоже возвращает true либо false.
$cake->isCheaper(...)
- Результат сравнения (применения оператора &&) тоже возвращает true либо false.
if (... && ...)
- Строка возвращает строку.
'Супер-скидка на торт'
- Оператор echo выводит строку и ничего не возвращает (null).
echo ...;
Обратили внимание, как сильно я раздробил код? Почти до атомов!
Примеры с возвращением
Часто ответ на третий вопрос дается сложнее всего. Давайте немного попрактикуемся и применим новые знания в задачах, а заодно и исправим ошибки в этих примерах.
Пример 1
$a = (bool)rand(0, 1);
if ($a == true) {
echo 'Истина';
}
Конструкция выводит слово "истина". Когда в переменной $a хранится значение true, управлять логикой мы никак не можем без изменения кода. Разберемся, что возвращается на каждых этапах.
- Случайное число 0 или 1.
rand(0, 1);
- Преобразование типа дает true либо false.
(bool)rand(...);
- Это значение помещается в переменную $a и возвращается.
$a = ...;
- Обращение к переменной возвращает ее значение: true либо false.
$a
- Возвращает true либо false, в зависимости от результата условия, если $a вернет true, то и выражение вернет true.
$a == true
- Ничего не возвращается, но выполняется в зависимости от условия
if (...) {
echo 'Истина';
}
Теперь, зная каждый шаг, можно увидеть ошибку. Посмотрите на шаги 3 и 4 - они возвращают одно и то же. Значит шаг 4 можно убрать. Так же в данном случае можно избавиться от переменной $a, она используется один раз.
if ((bool)rand(0, 1)) {
echo 'Истина';
}
Пример 2
($b > 5) ? $a = $b * $b : $a = 0;
Простой тернарный оператор, если в $b число больше 5, то в $a кладется квадрат этого числа, а если меньше, то 0. Разберемся, что происходит здесь, и улучшим код. Некоторые совсем очевидные шаги я пропущу. И пойду в другую сторону, от большего к меньшему
- Выполняется тернарное выражение и возвращается его результат.
... ? ... : ...;
- Возвращается результат, тот же, что и внутри скобок.
(...)
- Возвращается результат сравнения: true, либо false.
$b > 5
- Возвращается значение переменной $b.
$b
- В переменную $a кладется результат возведения $b в квадрат.
$a = $b * $b;
- В переменную $a кладется ноль.
$a = 0;
Нарушен принцип работы тернарного оператора. Он возвращает либо первое, либо второе значение в зависимости от условия. Значит, его не правильно применили, т.к. возвращаемое значение никуда не присваивается.
В двух последних шагах повторяется первая часть: "В переменную $a кладется". Так почему бы не вынести это дублирование из тернарного оператора? А на шаге 2 лишние скобки.
Смотрим, что получилось после исправления:
$a = $b > 5 ? $b * $b : 0;
Сколько лишнего кода удалось убрать, досконально разобравшись в его работе!
Резюме
Всегда, в любой части кода отвечайте себе на три вопроса: что эта часть кода делает, как ей можно управлять и что она возвращает. Тогда вы будете понимать зачем нужен этот код и будете читать его так, как читают профессионалы.
Именно знание ответов на эти вопросы в любой части кода поможет вам разобраться в коде в целом, понять и прочитать его. Поможет перестать вам запутываться в своих решениях и делать их оптимальнее и лучше. Со временем и практикой вам даже не придется останавливаться при беглом просмотре кода на каких-то его частях - вы на автомате будете знать ответы на эти вопросы.
Выживи сам - помоги другим.
Обычно я пишу код.
Профессиональный веб-разработчик со стажем 10+ лет. Все это время я провел в веб-разработке, участвовал в проектах различной сложности и обучал мастерству программирования новобранцев.
Делюсь своими знаниями и опытом!
Комментарии