Tempora mutantur et nos mutantur in illis
(времена меняются и мы меняемся вместе с ними — Овидий)
Ныне, кстати, tempora mutantur еще быстрее, чем в эпоху Овидия, и для нас, грешных, это означает, что требования к программам, которые мы разрабатываем, меняются быстрее, чем мы успеваем их разработать. Можно, конечно, спорить — хорошо это или плохо, но что это — реальность, с которой приходится считаться — думаю, не вызывает сомнений.
На практике сие означает, что в написанный код приходится вносить изменения уже в процессе его разработки, а затем — еще и в процессе сопровождения. А потому грамотный, с моей точки зрения, код должен — помимо прочего — обладать таким качеством, которое я бы назвал модификабельностью.
Дело, по сути, сводится к тому, чтобы внесение каких-либо изменений не обрушивало лавину согласованных изменений в самых неожиданных местах и тем более — во множестве файлов исходников. Это определение, вне всякого сомнения, не слишком научно — поскольку изменения так или иначе согласовывать приходится, строго говоря, любые, да и «лавина» — это сколько? 10, 30, 100?
Однако, интуитивно, мне кажется, понятно — о чем, собсссно, речь. Можно, поэтому, наверно, и сформулировать некоторые критерии модификабельности кода — без претензии на всеохватность — и, соотвественно, некоторые рекомендации.
Первое (и главное): код должен создаваться как модификабельный изначально. Разрабатывая его, будем помнить, что когда-нибудь кто-нибудь будет его переписывать. И важно, что сегодня мы даже в страшном сне не можем увидеть, как именно («аксиома неопределенности»). При этом, вполне возможно, что переписывать-то будем мы сами — когда начисто забудем, что и почему мы там понатыкали, а времени на то, чтобы вспомнить, у нас будет ровно до утра — когда назначена презентация продукта потенциальным инвесторам.
Второе: код должен быть структурирован в соответствии со структурой алгоритма. Мысль довольно туманная, но важная. К тому же она поддается некоторой (косвенной) конкретизации — соберем в одном месте все фрагменты, решающие одну локальную задачу, а которые разные — разнесем: желательно по отдельным модулям. Если используется константа (хрестоматийный пример), пусть единожды — определим ее в шапке соответствующего фрагмента: не будем забывать, что нам не дано предугадать не только, как наше слово отзовется, но и во скольких неожиданных местах отзовется оно, когда нам придется всё переписывать (см. «аксиому неопределенности» выше).
То же касается и законченных операций — соберем их в процедуру или функцию с подходящим названием — и вызовем; пусть это даже необходимо один раз: во-первых см. «аксиому неопределенности», а во-вторых это же — нагляднее, поскольку явно именует то, что мы делаем.
Помимо того, что это удобно чисто технически — важно еще и
Третье: чтобы код был ясным. Что означает — незапутанным и понятным. Проникнемся мыслью, что текст на любом языке программирования нужен-то человеку, а не машине, и будем проще, и там, где можно выбрать между «красотой» и ясностью — выберем ясность.
Дело это тоже, конечно, с трудом поддается формализации — что ясно одному, может быть совершенно неясно другому; но, к счастью, и здесь возможно предложить некоторую конкретизацию: в идеале код попросту должен читаться, как более-менее связный текст на английском. Были, конечно, на заре развития советской вычислительной техники ассемблеры с инструкциями типа «идти», «взять», или «переслать», однако случилось так, что именно английский ныне признан в качестве международного стандарта. Что теперь поделать; да и хорошо, что, например, не китайский — представьте язык программирования, основанный на иероглифах? представили?
Итак — ясность и еще раз — ясность. А уж остальное — дело оптимизатора, а не кодировщика и тем более — не программиста: задача последнего — придумать оптимальный алгоритм; путать это умение с умением сэкономить на двух присваиваниях, выполняемых каждый високосный год — есть, вообще-то, признак дилетантизма.
Ну и — комментарии; да, банально, я понимаю; я поэтому подумал-подумал и не стал выделять их в отдельный раздел. С другой стороны, комменарии комментариям — рознь: уж лучше никаких комметариев, чем
if(a>0) // :-) *_* (-: праверим что а менше 0 :-) *_* (-:
Поэтому, говоря честно, лучший комментарий — это сам код: если только он действительно грамотно написан.
Четвертое: код должен быть переносимым — «портабельным». В идеале — должен без потери качества идти на любой платформе, где есть соответствующая стандартам поддержка языка, на котором он написан.
Здесь я, наверно, задену чувства многих, кто считает, что настоящий «крутой программер» — знает все особенности регистровой пересылки в железе, с которым работает, и основывает на этом знании свою работу, а все остальные — суть ламеры.
Кхм... Господа! Использование сведений о деталях машинной реализации для написания кода, или — тем более — создания алгоритма — признак, некоторым образом, непрофессионализма. Профессионал — ясно это понимает и использует исключительно в тех случаях, когда обойтись без знания реализации нельзя уж никак — причем делает это с крайней неохотой, выделяя такой машинно-зависимый код в отдельный модуль.
(Здесь сразу хочу заметить, что хорошо всем известные средства автоматического конфигурирования отношения к сказанному не имеют ровно никакого — поскольку сам код при их использовании может быть переносимым, а может и не быть. Это скорее средства обойти проблему, чем ее решить; при этом их собственного качества с точки зрения, о которой я пишу, даже и не будем касаться.)
Профессиональный программист — и об этом писалось давно и многократно — вообще не обязан (а лучше всего — не должен иметь возможности) знать, как его программа будет исполняться — просто потому, что это будет побуждать его концентрироваться на ее сути, а не на множестве мелких деталей — получая более общее, а значит, в среднем, более надежное решение (об этом см. также здесь). Беда только, что ныне это, продиктованное здравым смыслом, положение совершенно забылось, и лишь это мешает осознать всю массу проблем, возникших в результате.
* * *
Итак, вот. Можно — как это бывает обычно — сделать еще много мелких замечаний по этому поводу, но ключевые моменты, как мне кажется, я упомянул. Разумеется речь шла о работе рутинной, профессиональной; о разработке кода, как таковой; есть много областей, где все эти положения не очень-то существенны, или несущественны вовсе: там, где работа идет по принципу «сделал и забыл» — однако в этом случае и говорить о профессионализме именно программирования не приходится.
С другой стороны, можно, конечно, сказать и так: «выброшу старый код совсем и напишу новый с 0» — однако, более крупных программных единиц всё сказанное касается в еще большей степени — например, замена любого программного модуля модернизированным, приводящая к необходимость переписывать заново все остальные, — еще менее желательна.
Словом, будем помнить, что все меняется, не будем рассчитывать, что пишем на века. Будем скромнее.
Recent Comments