15 NOV '14 |
Существуют некоторые определённые этапы построения рабочего кода, которые возникают сами по себе, стихийно, из одной лишь целесообразности на каждом этапе — но воспроизводятся и образуют систему, алгоритм.
1. Постановка общей задачи
На этом этапе всё уже работает. Мы можем сразу, мгновенно во всех подробностях представить себе созданную программу, увидеть её вывод, результат. Как писатель, ещё не начав книгу, уже видит её мир завершённым. Как архитектор видит здание, вписанное в местность, ещё даже не начав чертежи. Осталось только выполнить всю механическую часть.
2. Варианты решения
Возникают варианты, уже не стратегического плана, а тактического: как решить ту или иную второстепенную задачу, которая в числе прочих приведёт к реализации задуманного. Часто только на этом уровне абстракции мы и сталкиваемся с необходимостью что-то решать, видим подзадачу. В нашей первоначальной идее она была незаметна, была органично встроена в общее здание, подразумевалась решённой.
3. Порядок задач
Нам приходится определять, что реализовывать первым. Казалось бы, всё равно — но нет. Не всегда. Часто порядок вообще не может быть произвольным. Здание строится не со стен или с крыши, а с котлована, с фундамента. Но если у строителя порядок уже физически (и даже топологически, для пущей простоты: снизу-вверх, от несущего, базового — к второстепенному) определён и един не только на всю его жизнь, но и вообще на всю историю отрасли — то у программиста, писателя, художника (особенно у программиста) всякий раз порядок неожиданный (задача нова и уникальна), его приходится нащупывать, изобретать, сталкиваясь с тупиковыми вариантами, которые вроде бы годятся, но отчего-то работа так не идёт. При всей этой сложности, лучше всего бы решать этот этап мгновенно, интуитивно, и сразу правильно. И он не формализуется, слишком много надо учитывать, при неповторимости моделей задач и внутренней сложности их структур.
А иногда бывает, что нет жёсткой необходимости в той или иной последовательности. Или у каждого из альтернативных решений есть свои преимущества и недостатки. В этом случае есть две уловки:
- работать от приоритета; первыми выполнять те задачи, которые дадут наибольшее приближение всего проекта к итоговому результату — в его первоначальном идеальном образе; и одновременно те, что выполнять проще, что изначально яснее и потребуют меньше затрат;
- в случае серьёзной неразберихи с приоритетностью, когда действительно нет никаких маяков и иерархия не выстраивается — отважиться действовать наобум; просто взяться уже за что угодно — там видно будет; иногда огромные проекты сворачиваются и откладываются только из одного непонимания, что можно применить эту уловку, из отсутствия ориентиров, с какого конца взяться за распутывание их сложнейшего клубка внутренних связей и противоречий; так вот: с любого, рабочий процесс сам подскажет.
4. Пробный код
Порядок работ определён, мы идём по этапам его решения. И тут снова начинается творчество. Но уже иного плана, чем творчество на каждом из предыдущих этапов. Схоже, но немного по-другому уже.
Мы принимаем рабочую гипотезу. Нам кажется, что примерно такими известными нам способами, по такому алгоритму, мы вероятнее всего (и изящнее всего — а в программировании это самое важное: чтобы код был изящен, максимально лаконичен и прозрачен, и, следовательно, модифицируем в будущем) придём к решению. И реализуем это на практике. Иногда заходя в некоторые локальные тупики, и либо прорываясь через них с боем, либо отступая, найдя иной путь, лучший. Или даже решая что-то черновым способом, а потом находя ещё более элегантный алгоритм.
5. Вычистка, упорядочивание и комментирование кода
Когда код выполняет все задачи, которые были задуманы — это уже победа. Но это ещё не всё. Мы должны совершить дополнительные ритуальные действия, которые позволят вернуться к коду даже через многие годы, когда мы о нём совсем забудем, забудем его особенности, его внутреннюю логику, которая в каждом проекте неизбежно своя, частная, выстроенная для его целей и структуры:
- убрать отладочный вывод (а его зачастую много, и он даже оформлен красиво — и программисту он становится в процессе милее и ближе, чем уже давно наскучивший итоговый результат, ради которого вся возня и затевалась); но не так убрать, чтобы совсем — а, скорее, закомментировать; чтобы и в коде он не мешался, и в случае чего был снова доступен;
- оптимизировать все функции и объекты, создать максимально стройную структуру программы (ведь в процессе поисков рабочих алгоритмов мы не всегда писали самый простой код, нашей задачей было экспериментировать, достраивать уже частично сработавшие гипотезы, нашей задачей было, чтобы код просто сработал, выдал необходимое во всех его аспектах);
- отформатировать, пронумеровать и прокомментировать смысловые элементы кода, чтобы потом его можно было читать как прозрачную структуру, а не как монотонный поток: мгновенно находить нужное место, а не вчитываться в код, прогоняя через процессор своего воображения его строку за строкой, и удивляясь: «а здесь я зачем тогда такое решение использовал?»
- желательно сохранить в комментариях или отдельных сопроводительных документах (тем более, что времени это занимает немного) своего рода архив всех отключённых побочных ветвей кода, выполнявших полезные функции, которые не вошли в итоговую реализацию (в то время, как заведомо худшие и во всём превзойдённые итоговыми решениями следует смело выкидывать), но которые со временем зачем-то могут снова понадобиться; это же справедливо и в отношении литературного текста, и в отношении изобразительных искусств — черновики, неся в себе точно такой же результат сконцентрированного творческого труда, иногда могут впоследствии оказаться востребованы.
____________
Что интересно, так же работает творческое мышление в целом, создание сюжетов и снов. Мы вбрасываем произвольную гипотезу, ещё не подкреплённую никакими обоснованиями, сразу визуализируя её, и затем производим вычисления, пытаясь выстроить вокруг неё правдоподобный мир, в котором она могла бы существовать. И точно так же, если сталкиваемся внутри этой ещё незаконченной, динамичной, пока аморфной (что даёт на этом этапе творческую свободу), пребывающей в развитии конструкции с неразрешимыми противоречиями, корректируем изначальный замысел. И дополняем его до тех пор, пока единая стройная и работающая концепция не будет завершена. Те же шаги: предположение, обоснование, корректировка, дополнение, завершение, финальная отделка.
| |