Говоря о программировании, его часто разделяют на уровни: “programming in the large” и “programming in the small” (есть конечно искушение перевести их как “программирование по-большому” и “по-маленькому”, но пожалуй, не стоит).
Первое - это соответственно уровень дизайна, архитектуры и больших единиц программ, вроде модулей и библиотек. Второй - гораздо ближе к нам, это непосредстенно код, функции, выражения, переменные и т.д.
Новички часто фокусируются на “in small” первое время, что, логично и правильно. Большинство программ начинающих фокусируются на единственной задаче уровень архитектуры не особенно и нужен. Но при переходе от простых скриптов к приложениям дизайн начинает играть всё большую роль, и приходится волей-неволей задумываться об отношениях объектов и подсистем в проекте.
Акценты немного смещаются, но in-small
то от нас никуда не делся,
вот он тут всё еще пока мы размышляем о высоких материях, реальную работу
выполняет код - функции/методы, выражения и т.п.
Одна из главных прелестей программирования в том, что в 99% случаем ошибаться простительно.
Серьёзно, нет другой области где к ошибкам относились бы также снисходительно
пока работодателю это не стоит слишком много денег, а для научения
чему угодно один из лучших путей это действие-ошибка-корректировка.
Поэтому в повседневной in small
практике такая схема до боли знакома нам:
- написать код.
- получить удар под дых от ошибки краша, забыл-изменить-параметр-в-другом-месте
- подумать и сделать получше, а еще круче так, чтобы сделать такую ошибку невозможной.
Набив шишки заметно, что у многих акцент смещается в пользу так называемого
defensive programming.
Заранее признав склонность человека (себя в первую очередь) к ошибкам,
начинаешь подозревать что расставлять везде assert
ы идея совсем не плохая.
Пример: допустим, есть у нас функция с кучей параметров, перепутать порядок аргументов в такой ситуации проще простого:
def connect(db_name, user, password, host, port): ...
Подстраховать себя можно, соединив это с использованием словаря:
conn_creds = {
"db_name": st.DB_NAME,
"user": st.DB_USER,
"password": st.DB_PASSWORD,
"host": st.DB_HOST,
"port": st.DB_PORT,
}
conn = connect(**conn_creds)
Зайдя ещё чуть дальше, в Python
можно даже сделать
вызов функции keyword-only
полностью:
def connect(*, db_name, user, password, host, port): ...
Такой подход гарантирует корректный вызов (или сразу KeyError
если
мы напортачили с параметрами).
Без этого хорошо если неверный порядок приведёт к скорой ошибке, а не к
неожиданному и непонятному поведению - отловить такое потом чертовски сложно.
С опытом у многих накапливается целый арсенал таких “трюков”, позволяющих
сделать код попросту более надежным, дать немного стабильных гарантий,
или хотя бы подстелить соломку. А дав программе надежности in small
гораздо проще размышлять о ней in large
, меньше беспокоясь о мелких деталях.
И мне кажется, приобрести такой набор можно только методом проб и ошибок, иначе наш мозг просто не прочувствует всю необходимость такого подхода.