Трюки в программировании in small


Говоря о программировании, его часто разделяют на уровни: “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, меньше беспокоясь о мелких деталях. И мне кажется, приобрести такой набор можно только методом проб и ошибок, иначе наш мозг просто не прочувствует всю необходимость такого подхода.