Pull to refresh

Comments 106

Ну уж нет, программирование — это искусство. И никто меня в этом не переубедит.
Искусство и ремесло не исключают друг друга
Искусство становится искусством, когда в достаточной мере овладел ремеслом.
Ну и инженерию противопоставлять не стоит. Software engineer же.
Искусство — это диаграмки в UML рисовать, например. Удел так называемых «архитекторов». Как только дело доходит от красивых бумажек до работающего кода — это больше становится ремеслом.
Немного не туда ответил
Мне кажется, что в статье шла речь не о Software Engineer, а о Programmer (Coder). Это все-таки разные вещи, разные требование и разные зарплаты. Кодер это, действительно, больше ремесло, нежели инженерная профессия. Нужно хорошо знать язык, не допускать утечек памяти и т.д. А вот Software Engineer приходится и UML-диаграммы рисовать и вообще весь аспект работы смещен в сторону проектривания, а не собственно написания кода.
Да, похоже, вы правы.
Я надеюсь, Вы не Босх от программирования. Иначе мне жаль Ваших коллег, которым приходится видеть (и сопровождать) Ваш код.
Вы видели то «искусство», которое херачат даже самые крутые разработчики перед дедлайном?

Программирование — типичное инженерное ремесло. Но как в любом инженерном деле — в нем есть достаточно места для искусства.
Программирование в большинстве случаев это не искусство, поскольку заказчика (не важно внешнего или внутреннего) интересует результат работы программы, а не её красота (в смысле красота кода). Это как фотография — отдельные личности участвуют в выставках или посещают их, спорят о «заваленном горизонте» (фиг знает что такое, но даже на хабре часто встречается) или неправильной выдержке/диафрагме, но большинству на это наплевать, им главное «остановить мгновение».
Красота кода обычно (хоть и не всегда) имеет некоторые побочные эффекты — красивый код зачастую корректнее и оптимальнее уродливого. Так что если заказчика интересует чтобы программа не глючила, выдавала корректный результат и делала это быстро — его интересует и красота кода, даже если он об этом не подозревает. Другое дело, что многих заказчиков всё это не интересует — им важнее чтобы программа была готова как можно раньше, как можно дешевле, и при этом выглядела более-менее работающей. В этом случае красота кода их действительно не интересует. Но с такими заказчиками можно просто не работать, если Вы уважаете свой труд и не хотите тратить время своей жизни на создание говна на благо современной копроэкономики.
Во французском языке искусство и ремесло есть суть однокоренные слова. Это в русском как-то не срослось. При этом ремесло оно как основа для искусства.
А не наоборот? Искусство вырождается в ремесло, когда методики искусства формализуются и становятся доступными почти каждому, потратившему время на их изучение. Нет?
При этом хороший ремесленник характеризуется словом «искусный».
Извините, но первый раз об этом слышу. Вы не могли бы уточнить? Ведь ремесло — le métier, а искусство всегда было и есть l'art. Они могут употребляться вместе, но и тут их значение даже не синонимично.
UFO just landed and posted this here
Вот именно, что у молодежи. Я тоже в начале считал программирование искусством, но лет через 10-15 стал относиться к программированию как к ремеслу.
Верно. Для них оно и в самом деле является искусством, местами даже изобретательской деятельностью. А когда набирается опыт и пропадает жажда экспериментов — одни остаются и становятся профессиональными «ремесленниками», а другие начинают скучать и уходят в менеджеры и другие специальности.
Ну, тут может не только ваше личное мнение изменилось, но и само содержание программирования. Лет 15 назад тупо не было такого количества инструментов, которым мы пользуемся сейчас как должным, или не было к ним доступа (в 97-м интернет далеко не у каждого разработчика был, равно как и возможность купить нужную книгу), а те что были не были столь совершенны и приходилось применять искусство делать из говна конфетку или делать её с нуля (ещё неизвестно что большее искусство).
UFO just landed and posted this here
В начале программирование вовсе кажется магией.
Для меня магией являлось (да и является) проектирование железа. Как так, что «проводочки» и «детальки» понимают смысл моих команд? Не, разумом я понимаю, что не боги горшки обжигают и что, например, потратив некоторое количество времени я смогу спроектировать микропроцессор уровня, скажем, i8080. Но эмоционально для меня магия даже простой калькулятор с четырьмя действиями и тремя (первый операнд, операция и второй) регистрами. А какая магия в том чтобы отдавать команды которые (почти) беспрекословно исполняются? Командовать все умеют :)
Пункт №0 сам по себе вызовет негодование у неайтишников. Не знаю, специально ли автор начал с нуля, но это очень типично. Сам несколько раз наблюдал, как программисты, сами того не замечая, первый пункт обозначают цифрой ноль. Привычка… что поделаешь?
Я бы понял если бы у айтишников: элитарность, художники-творцы и т. п. — каждый где-то в глубине души в это хочет верить. Но у неайтишников-то почему? У меня, как не у музыканта, не вызывает негодования, что, например, умение сочинять музыку и слова к ней превратилось, похоже, в ремесло. И что, возможно, недалёк тот день, когда айтишники превратят его даже не в ремесло, требующее хоть какого-то образования, умений, навыков, а просто в ответы на вопросы «визарда».
UFO just landed and posted this here
Ну а Кнут что, зря свою книгу так назвал? Всё зависит от. Просто востребованным является ваяние формочек поверх БД, и там ничего нового или интересного нет, всё давно уже известно и понятно. Автор оригинала говорит, что использует готовые инструменты. Но ведь и инструменты кто-то делает, не так ли? Таких людей хоть и мало, но они есть.
Вот своей книгой он и превратил искусство в ремесло. :) И даже смайлик может не уместен.
К сожалени, пункт 4 не всегда воплотим, особенно когда нет множественного наследования.
Прокси проблему решить не может? Какое-то дублирование, конечно, будет, но это будет не дублирование логики.
Да, конечно может. Но когда большая система, и когда «проксей» много, код тоже начинает терять надежность и читабельность. Приходится искать баланс между дублированием и, скажем так, качеством кода.
Ну, по мне так общая читабельность выше когда логика не дублируется. Хотя бы потому что изучая проект и в двух методах разных классов увидев только вызов метода третьего класса, я прочитаю детально его тело только в первый раз, а во второй довольствуюсь названием метода, в крайнем случае бегло в него заглянув. А вот увидев тело этой логики в двух методах придётся вчитываться в каждую, да ещё сравнивать и искать отличия и думать почему же не объединены, должен же быть подвох, почему предпочли копипаст выделению.

P.S. Просьба, если уж вы дублируете код в разных местах, то ставьте в комментах указание что вы дублируете, хотя бы сам факт дублирования, а лучше и причину.
Да. но повторюсь — НЕ ВСЕГДА можно избежать дублирования.
Вот честно, не представляю себе такую ситуацию, если речь не идёт о паре строк. Можно попросить пример привести?
Простой пример не привести, конечно. Но в больших системах приходится с таким сталкиваться. Когда надо логику разнести на разные компоненты, когда сложное взаимодействие огранизовано, но компоненты имеют иногда схожую логику, а соединить вместе нельзя (в том числе и по лицензионным причинам с третьими компаниями). Пригодилось бы множественное наследование, но его нет… иногда приходится писать скрипты для сборки, чтобы копировать куски кода.
Всё зависит от размера этой «пары строк».
Если ради избегания дублирования небольшого куска нужно навешать лапшу из наследований и проксей на пару сотен строк — то это уже повод задуматься.

В крайнем случае можно и макросом воспользоваться, чтобы «замаскировать» дублирование в этом случае.
воплотим но может требовать непропорционально большого изменения архитектуры
Ну именно это я и понимаю под «не воплотим». То есть «не воплотим в нащих реалиях».
Интересно, какой процент сообщества согласны с пунктом 3 насчет отладчиков? Как-то так получилось, что отладчиками я не пользуюсь с самого начала деятельности. Как-то не нужны они мне — достаточно внимательно смотреть на код и вставлять в разных местах print или тому подобное. Мне кажется, что с отладчиками я бы находил причины ошибок больше времени.
кто как приучился, я думаю.
С помощью отладчика удавалось находить ошибки, которые не дают о себе знать на первых порах.
Брейкпоинты — отличная идея
Отладчик хорош, когда можно все «первые поры» и не только проиграть у себя в песочнице.
А когда код улетел в продакшн — у некоторых клиентов могут быть настолько суровые NDA, что даже бэктрейс вылета будут цензурить перед тем, как вам показать. А уж о доступе «к телу» и речи нет.
Тут скорее дело привычки, кто чем пользуется то ему и удобно. Я пользуюсь и тем и тем, так как принт или cout не всегда можно написать.
Для меня вставлять print или какой-нибудь var_dump это вариант использования отладчика только кастрированный. И явно быстрее вставить точку останова, чем в то же место вставить print. В IDE, конечно, а не в блокноте. Другое дело, что от отладчиков, что полноценных, что кастрированных, я почти полностью отказался после того как стал широко применять юнит-тесты и исключения на каждый чих — просто нет нужды. Жаль только, что в основном языке стандартная библиотека исключениями пренебрегает, приходится самому писать нечто вроде if (func()) throw new SomeException;.
Я почти не пользуюсь отладчиком. Правильно и обильно расставленные ассерты и неожиданно появившаяся в консоли строчка-предупреждение дают мне как правило больше информации чем состояние многопоточной программы которое я могу видеть в отладчике. Ассерты позволяют «раннее детектирование» проблемы на этапе тестовых прогонов, и локализация ошибки происходит значительно быстрее.
Отладчик — это средство для выяснения тех мест, где нужно поставить лог/ассерт ;)
Это только на «нулевой стадии».
А клиент соберёт себе релизную версию, где все ассерты улетят в null, а отладочные сообщения обрежутся (дабы не тормозить процесс в целом).
Самые редкие баги обычно так и случаются.
И (что самое обидное) они действительно находятся в Вашей программе, а не являются следствием оптимизации при компиляции. И вот тогда быстрее будет попросить шелл, пересобрать отладочную версию и запустить под gdb, чем ковырять авгиевы конюшни стрипнутых бинарников и бэктрейсов от заинлайненых сущностей.
Да, я согласен. Ассерты — не 100%-панацея от багов и проблем.
К сожалению, у меня нет возможности «попросить шелл» и «запустить под gdb» те приложения, которые я разрабатываю :)
Особенно в том самом «окружении», в котором происходит проблема.
Я просто хотел подтвердить тезис о том, что отладчик — не самый важный инструмент в некоторых разработках.
Точки останова и отладка по шагам значительно быстрее всевозможных print.
Правда, нужно помнить, что отладка не заменяет логов, а логи не заменяют отладку.
КМК, отладчик отучает думать. Программист пытается разобраться с проблемой постфактум, уже написав код, а не изучая тонкие места в процессе написания (assert, cout).
Я думаю вы согласитесь, что «тонкие» места программы проще держать в памяти во время написания кода, а не после его релиза. В этом плане assert и cout являются чем-то вроде юнит-тестов, только для меньших участков кода.
cout (print?) является для меня примитивным отладчиком, assert — да, мини-юнит-тест. Но чем вывод переменной в консоль отличается от её вывода в отладчик?
Как минимум тем, что это быстрее. И тем, что вы вряд ли будете запусать отладчик во время написания сложного метода, а вот вывод в консоль состояния памяти оставить не так сложно. Также стоит добавить, что отсутствие отладчика дисциплинирует (мы не ищем легких путей). Если программист знает, что у него нет под рукой отладчика, чтобы понять «что этот странный кусок кода делает», то он приложит максимум усилий, чтобы по-настоящему хорошо разобраться в нем используя консольный вывод и здравую логику.
Как результат — он лучше сможет представить сценарий работы отдельно взятого метода, а в долгосрочной перспективе — всего проекта в целом.
Для меня быстрее ткнуть справа от присваивания мышкой, чем писать var_dump после присваивания, сохранять, коммитить в дев-ветку и смотреть вывод (это ещё язык у меня интерпретируемый, а если компилируемый, да ещё и не инкрметно...).

Насчёт дисциплинирования согласен, но для меня инструментом дисциплинирования стали юнит-тесты, а не отладочный вывод. Если я не могу понять почему фэйлит тест, значит этот тест уже не юнит и надо рефакторить код.
Вывод в консоль или в файл влияет на работу программ.
Например, многопоточные программы в некоторых случаях могут продолжать работать при включенных логах, но начинают падать при отключении логирования.
Вы в одиночку всегда пишете? Не приходилось разбираться с чужими библиотеками? Просто с кодом коллег?
Я не в состоянии держать в памяти «тонкие» места, которые написаны не мной.
Одно не противоречит другому.
И — всё ОЧЕНЬ сильно зависит от контекста.
я не думаю, что многопоточную программу, управляемую событиями будет проще отладить, чем отлоггировать/отпрофилировать.
А вот какую-нибудь пузырьковую сортировку в одну ветку — да, проще в отладчике.
Я действительно говорил об отладке одного потока.
Отладить программу с проблемами, непосредственно вызванными многопоточностью (синхронизация, блокировки, совместный доступ) — это в любом случае тяжелая задача, хоть чем пользуйся ;)
На GPU спасают только тесты и отладчик. printf — поддерживается в новых видюхах, а вот логи нужно дополнительно вкорячивать (самостоятельно создавать буферы сообщений, учитывая, что память GPU не резиновая). При тысячах–миллионах потоков — приятного чтения логов)!
Сейчас правда ещё поддержка assert'ов появилась.
Мне найти, почему программа делает НЕХ вместо того, что должна была бы, гораздо проще с помощью отладчика. Можно сразу посмотреть, что происходит с переменными по стеку вызова. Много шансов, что за один такой просмотр можно сразу и решить, почему что-то идет не так.

Не использовать дебаггер только от того, что с помощью него легче что-то находить, и что он расслабляет мозги — это такой же студенческий бред, как и программировать в блокноте, писать на асме, потому что он ТРУЪ, или использовать эклипс вместо идеи, потому что «оно open source».
Плохому программисту всегда будет что-то мешать, а хорошему нужен хороший инструмент.
Без отладчика можно только предполагать что делает программа, под отладчиком — видеть как программа выполняется. Особенно, если эта программа не покрыта юнит-тестами, или взаимодействует с другими программами.

Отладчик в ряде случаев просто незаменим:
* Отладка приложений при загрузке/выгрузке системы с использованием ядерного отладчика (сервисы, boot-time приложения (autochk.exe), драйвера).
* Анализ креш-дампов.

Какой смысл не использовать готовый, надежный инструмент в пользу наколенных решений в виде логов?
Отладчик бывает совершенно бесполезен в многопоточной программе. А использовать Soft-Ice для отладки прикладной программы это стрельба из пушек по воробьям.
Некоторые люди одержимы каким-то одним языком и думают, что этот язык подходит для чего угодно. Ошибочно так думать. Нет языка на все случаи жизни.

Даже если сам не одержим, то одержимы могут быть заказчики/начальники. То есть постановка задачи уже включает конкретный инструмент, и ладно ещё язык, но может быть и фреймворк, и CMS. А доказывать что есть (технически) лучшие для этой задачи решения обычно непродуктивно.

Я полагаю, что крайне важно поднимаясь вверх от CPU до языка, который ты используешь, понимать на каком слое что происходит.

Зачастую очень непродуктивен такой подход. Если, скажем, операция вызова функции не является узким местом, то изучать как она реализована в машкоде смысла особого нет. Сначала запускаем профайлер, ищем место которое тормозит, а потом ищем способ его оптимизировать.

С остальным согласен в принципе.
Ага, вот написали фейсбук на PHP, потом запустили профайлер и поняли, что именно надо оптимизировать. До сих пор ищут способ «разогнать» интерпретатор.
Не видел технические ченжлоги движка фэйсбука, но подозреваю, что а) далеко не сразу после запуска в паблике уперлись в производительность PHP и б) было бы выгодно переписать PHP код на C++ ручками — не стали бы писать hiphop.
И, главное, в) писали бы изначально на C++ не имели бы такой популярности сейчас.
Наверное, с фейсбуком получился неудачный пример (пример ближе скорее к 5 пункту).

Давайте рассмотрим несколько иную ситуацию. Скажем, есть некая кеширующая библиотека, которая является для вас черным ящиком. И вы совсем ничего не знаете о том, как именно внутри она работает. Более того, скажем, вы не знаете что такое хеш-таблица в принципе и как асимптотически растет время доступа к элементам с одинаковыми хешами. В такой ситуации очень вероятно, что рано или поздно ваше приложение начнет довольно сильно «подвисать». Вы запустите профайлер и обнаружите узкое место. Находите исходники библиотеки и читаете про коллизии. А дальше-то что? Вся ваша архитектура завязана на использование данной библиотеки. Переписывать приложение заново? Вставлять костыли? Искать новую библиотеку, которая использует деревья поиска? Мне кажется, если понимать изначально что и как работает на каком слое, то подобных проблем можно избежать. Безусловно невозможно знать всё, но ведь статья говорит о том, к чему надо стремиться.

Завязывание архитектуры на библиотеку говорит об отсутствии слоёв в принципе. По крайней мере в данном случае об отсутствии слоя кэширования. А при его наличии заменить библиотеку на другую не составит особой сложности. Даже без понимания принципов, чисто методом тыка :)

А вообще, по-моему, речь в этом пункте не о слоях архитектуры приложения (то есть своих слоях), а о слоях среды исполнения (чужих). Ну незачем мне вникать в особенности интерпретации PHP кода или компиляции C# кода, пока это не становится узким местом.
Методом тыка, может, и получится, но не всегда и не везде.
А когда место станет узким, не будет достаточно времени разобраться в причинах и решением будет костыль, найденный на форуме. Было бы понимание изначально — костыль бы не появился.
Как решение может называться костылём, если оно изолировано от ниже- и вышележащих слоёв? Для меня костыль — это решение, которое резко нарушает малую связанность.
Чтобы решить проблему внутри слоя, надо разобраться в проблеме и как слой работает, так?
Чтобы решить проблему внути слоя — так, но зачастую проблема снаружи слоя (слой как чёрный ящик работает некорректно) решается заменой слоя. Заменой библиотеки, работающей с хэшами на библиотеку работающую с деревьями поиска, например.
Если честно, я немного устал от спора :)
Уверен, вы поняли, что я хотел сказать. Возможно, бездумная замена библиотеки поможет в каком-то одном конкретном случае, но это лишь частность. И в идеале нужно понимать процессы максимально глубоко и задолго заранее появления проблемы, чтобы избежать лишней траты времени на обучение и поиск ошибки в продакшене.
Безусловно, кто-то специалист в вебе, кто-то в криптографии, кто-то в компиляторах, но базу нужно знать всем. И чем больше эта база у программиста — тем лучше.
Спасибо за дискуссию :)
Надеюсь и вы поняли меня. Истина, наверное, где-то посередине :)

И вам спасибо.
UFO just landed and posted this here
Спасибо за то, что поделились опытом, но хочется отметить, что все, о чем Вы рассказали, и даже больше — есть в книжке «Программист-прагматик».
Ок, я передам это Джону
Интересно посмотреть код, программирующего 30 лет и считающего себя ремесленником :)
Думаю, очень много использования библиотек, фреймворков, паттернов и прочих готовых решений с минимальной связанностью. Составление решения задачи из готовых кирпичиков с осознованием их узких мест. А нет осознавания — есть профайлер и знание слоёв.
Ага, и 100% проектов это что-то вроде «управление данными положенными в БД»?
100% проектов — управление данными, обычно персистентными. Персистентность может быть обеспечена СУБД, а может, например, облачным хранилищем с REST-like API. С хорошей архитектурой это не должно иметь значения в плане кода.

А вообще смысл в том, что самописные решения в коде такого человека, наверняка появляются только если готовых не существуют или они не удовлетворяют каким-то требованиям. А основной код — это склейка готовых решений. Вы разве не пользуетесь таким подходом? Пишите, например, вычисление синуса и косинуса сами, если в ТЗ стоит формула с синусом и косинусом?
Ну вот и ответ про «ремесленника», 100% однотипных проектов. Это ужасно по моему. ИМХО программист развивается только если выполняет такую задачу которую на момент начала выполнения он не знал как делать.
Кто говорил об однотипных проектах? Управление данными это единственная задача любой программы. Хотя нет, не любой, есть задачи типа нагрузить процессор или видеокарту по максимуму, чтобы проверить его устойчивость к нагрузке и пофиг на данные.

А «не знал как делать» слишком общее описание задачи. Самое просто разделение на подзадачи: не знал алгоритма или не знал как алгоритм приемлемо реализовать.
Берите выше: «алгоритма не существовало»
На днях на глаза попадалось где-то, что задача программиста по существующей модели разработать алгоритмы и реализовать их в коде.
Как будто кто-то кодирует по-другому, особенно сейчас :)
Ещё, имхо, в пункте "4. За дублирование придется поплатиться" есть один подвох. Если с этим переусердствовать, то можно подвести по сути разные случаи под одну гребёнку.
Т.е. если два куска кода решают с виду одинаковые задачи, но по сути они разные, то написание для них общего кода может потом аукнуться проблемами.
Например, вы у вас в системе есть 2 разных протокола (допустим, для 2х типов клиентов), и так случилось, что одна команда и там, и там, совпадает по набору аргументов. В этом случае если у них будет общий код (допустим для парсинга), то изменения в одном, затронут и другой, чего по логике быть не должно, и это будет неприятной неожиданностью.
Пример, конечно, сильно утрирован, но суть объясняет.
Нужно вовремя объединять и вовремя разъединять.
Прочитал, скучая.
Наверное, это неплохой посыл для новичков. Стоит им воспользоваться.

Хотя очень спорные моменты есть, и применимы они лишь в контексте решаемых проблем, но не в общем случае:
6. Проще надстроить программу чем построить ее сразу
Старина Хэнк был бы очень недоволен такому подходу к архитектуре и проектированию. Если вы не понимаете, то либо вам дали неправильное задание, либо ваш уровень недостаточен и надо развиваться (или сменить работу). В общем такой подход совсем не рабочий для коммерческих проектов, где эта задача разбита между руководителем, архитектором и проектировщиком. Хотя в стартапах-комбайнах или в индивидуальном порядке это может быть оправдано.

7. Изучай как устроены слои
Это тоже не всегда оправдано, особенно с позиции бизнеса. Изучение всей структуры и смежных областей = похвально, но ведёт к перерасходу времени. И для решения бизнес-проектов с чёткой спецификацией и временными требованиями это не применимо. В-общем, ничего плохого нет в том, чтобы ремесленнику из пункта 0 знать мастерски свой профиль, и не вдаваться в подробности, где выкован его инструмент и сколько угля было на него затрачено. Нельзя объять необъятное, хотя широкопрофильные, и подкованные даже в изящных искусствах советские инженеры — это действительно круто; но помимо такой широты программисту нужна гибкость и постоянное совершенствование своего инструмента, его заточка, и вышивка на чехле отходит на второй план.
В общем такой подход совсем не рабочий для коммерческих проектов,

Agile методики вполне себя оправдывают в коммерческих проектах. А «стартап» или нет, это форма бизнеса, а не разработки. Может быть стартап с водопадом, а может быть традиционный бизнес (нацеленный на операционную прибыль, ане на рост капитализации) с гибкими методиками.
0. Программирование удел ремесленника, а не ученого или инженера
В большинстве случаев да, но скажите об этом всем им
Кто-то из перечисленных писал код для аутсорс-проекта в какой-нибудь SuperSoft Puper Luxeware? Они как раз таки ученые.
Причем тут аутсорс-проекты? Автор пишет, что программирование не удел ученых, я говорю, что это не всегда так. Эти люди ученые и программисты — это опровергает утверждение автора (в некоторых случаях), что я сказал не так?
а сколько лет вообще John Graham-Cumming? 30 лет программирования, а всего сколько? Какой-то секретный тип, нигде никакой биографии, ничего о личной жизни.
с 2-7 соглашусь.
насчёт 1) всё-таки считаю искусством, но в программировании много ремесла.
Не согласен насчет отладчика, это один из важнейших моих инструментов. Никто не отказывается от ножей из-за того, что ими можно порезаться! Если отладчик серьезно упрощает мне жизнь и сокращает время разработки, то почему я не должен им пользоваться?
Если это упрощает жизнь и сокращает время, то пользуйтесь на здоровье. Именно для этого отладчики и придуманы.

Но на мой взгляд, типичный паттерн работы с отладчиком такой: есть алгоритм, который работает-работает, а потом бац! мы оказались в каком-то месте программы, где вообще-то не должны были оказаться либо должны были, но с другими данными. Ошибка *уже* произошла, но мы пока представления не имеем о её характере. Хорошо, запускаем программу под отладчиком и начинаем пытаться приблизиться к ошибке «слева». То есть правильно? дальше! правильно? дальше! правильно?.. нет тут так уже не должно быть. Пропустили багу. Ставим точку останова на последней «правильной» инструкции, запускаем отладчик сначала и снова пытаемся подойти к проблеме «слева».

В конце концов мы найдем то самое место, где выполнение программы сворачивает не по той стрелке, но придется рассмотреть код на многих логических уровнях и вспомнить что же этот код делает. (Тут вспоминаем про читабельность, материмся на лишние или отсутствующие комментарии, и пр.)

Правильно же поставленный ассерт вам даст место возникшей проблемы вплоть до строчки кода, а иногда и посоветует что именно надо сделать. Расставлять при написании кода такие ассерты, которые позволят тебе впоследствии сэкономить время на отладке — это именно то самое ремесло, к которому приходишь с опытом.
Может лучше вместо правильного расставления ассертов правильно писать код? :)
6. Проще надстроить программу чем построить ее сразу

Этот пункт тесно связан с пунктом №2. Начни с малого и надстраивай. Когда ты решаешь проблему куда проще начать с маленьких блоков(возможно сделав заглушки для каких-то частей) нежели проектировать архитектуру от начала до конца.

Когда ты строишь архитектуру от начала до конца ты 1) делаешь это неверно 2) получаешь в итоге нечто большое и сложное, куда будет очень трудно вносить изменения. С другой стороны если ты используешь маленькие блоки, которые взаимодействует между собой, рефакторинг будет проще в момент, когда ты поймешь что сделал ошибку в самом начале.

Причина в том, что нет способа узнать как должна выглядеть та самая правильная архитектура. Лишь в редких случаях можно сказать какие будут внешние воздействия на программу. Ты можешь утверждать, что тебе известен характер входящего TCP трафика, который обрабатывает твой мэйл сервер, или количество пользователей, или что ты никогда не слышал про спам. Так или иначе будет нечто извне, что начисто разрушит все твои предположения, и вот если эти предположения касались большой, сильно связанной и сложной системы у тебя большие проблемы парень.


Это самый главный пункт.
Он работает и в проектах, и вообще везде. Жизнь — это как шахматы. Чем дальше просчитываешь, тем больше вариантов. Верный, как правило, один-два (по сравнение с N->inf просто const). Поэтому вероятность успеха для просчета будущих N итераций P(N) = const/N, очевидно, стремится к нулю при N->inf.

Поэтому не наебывайте себя. Чем раньше вы в крови усвоите этот принцип, тем успешнее будете везде. Стартапы, быстро сделанные и быстро переделываемые (потому что говнокод, сделанный быстро, не жалко переделать и можно сделать это быстро), быстрее эволюционируют и быстрее завоевывают рынки.

Архитектура, которая быстро эволюционирует в начале проекта до полного понимания требований, устойчивее и лучше.

Быстрое накопление опыта и эволюционирование в любой сфере лучше тупого долбежа одного направления.

… итак, допустим, ваш когнитивный диссонанс прокачал вас, ведь программисты — одни из умнейших людей на свете (вспомните Профессия Азимова — нас один на миллион)
Кажется, да, поняв направление, можно делать сразу крутую и большую архитектуру. Еще одна ошибка. Пусть архитектура эволюционирует, но в крутые маленькие, быстрые кирпичики. В конце-концов, вы не умнее всех на свете. Посмотрите:
— в ООП говорят про low coupling, high cohesion
— MVC — взаимозаменяемость
— SOLID: DIP — взаимозаменяемость
— Unix way: Пишите программы, которые делают что-то одно и делают это хорошо; которые бы работали вместе; которые бы поддерживали текстовые потоки, поскольку это универсальный интерфейс
— эта статья: «сродни философии „слабо связанных кирпичиков“
— нормализация в БД
и тд

Поэтому, лучше, если вы придете к этому сейчас на чужом опыте.

Везде нужны небольшие компоненты, работающие по принципам SOLID. Если это бизнес-процессы, то каждый отдел имеет свою функцию и прозрачный интерфейс для работы с другими, а графы зависимостей ацикличны.

Если вы делаете проект, то в нем разделы разбиты по ответственностям, данные аггрегируются с умом и т.д.

Так и в проектировании интерфейса — у любой функции одно место, логика взаимодействия проста и понятна, желательно ациклична. и тд

В общем, Unix way рулит, итеративность рулит, водопадные и „ща спроектирую все сразу“ нахуй.

Когда что-то делаешь то сначала конечный результат должен быть сделан в воображении и только потом в реальности.
Ремесленник имеет некий набор известных результатов и сразу может приступать к реализации, как только поймет что из этого надо. Есть другая профессия — дизайнер, которые придумывает новые вещи. Конечно очень хороший ремесленник может быть дизайнером но это нечто дополняющее ремесло, а не присущее ему изначально.

Программирование же включает в себя дизайн и только очень хорошие и опытные могут работать как ремесленники и выдавать стабильный результат. Могут но не должны ограничиваться.

Человек писавший статью явно отрицает творческую составляющую профессии и тем самым ограничивает себя. Отсюда и весь тот бред про архитектуру и прочее в последних пунктах. Хотя с отдельными вещами можно согласиться.
Человек пишет о своем опыте, ну ремесленник он, что тут поделать.

Уверен, что код одних — искусство, а код других ремесло, при этом работать могут оба, и вероятно даже одинаково эффективно. Разницу становится видно, когда этот код нужно поддерживать или дополнить. Чтобы выполнить пункт №2 (упрощать) нужно быть в какой то мере гением, либо очень хорошим ремесленником. И хотя я допускаю факт существования вторых, сам лично я с такими не знаком.

Талантливым людям опыт дает очень многое, другие же годами стоят на месте.

А работодателям вообще без разницы, искусство это или ремесло, все что ему нужно знать (и они это знают) что одни люди пишут быстро и хорошо, а код других приходится выбрасывать.
может, он имел в виду под ремеслом использование готовых решений, как-то библиотеки, фреймворки и т.д.
Я в конце концов изменил свою точку зрения, потому что нашел для себя довод в пользу того что программирование не искусство.

Взять знаменитую картину Малевича «Черный квадрат». С точки зрения искусства эта картина имеет смысл. Но код, представляющий из себя подобный арт не принесет никакой пользы. В этом в общем-то и отличие. Код программиста хорош, только тогда, когда приносит пользу, посему это все таки ремесло.
Польза-то польза, но в то же время нужно сделать так, чтобы потом было легко его допиливать, чтобы не было такого, что в одном месте ты поправил, а в другом из-за этого упало.
Если написать такой код это не исскуство, то скорее уже не ремесло.

Если писать, не думая, то код может приносить пользу до первых изменений в него.

написать код в большой UI-программе это как навести порядок в большой комнате, в которой много вещей.
Ну это уже зависит от трактовки слова «польза». Легкая допиливаемость кода это тоже польза, код может быть при этом конечно красив, но это не «арт».

Арт это брейнфак и некоторые конструкции на перле. При просмотре такого кода можно получить эстетическое удовлетворение, и он даже будет работать. Но понятный и легко изменяемый код в конечном итоге приносит больше пользы.
Что-то все прицепились к спору о том что программирование — это ремесло. Я согласен с этим утверждением. понял это в какой-то момент.

Но на самом деле я хочу выразить благодарность автору. Замечательная, приятная и мудрая статья! У меня не 30 лет опыта, но каждый пункт точно синхронизируется с моим мнением. Особенно поразило про отладчики и логи, именно так я всегда и делал дебаг — оно как-то проще и логичнее ) Надеюсь Вы напишите ещё какие-нибудь статьи! Лишь бы не пропустить )
Sign up to leave a comment.

Articles