Программирование без кода: обзор инструментов

Репозиторий для хранения исходников

Репо­зи­то­рий — спе­ци­аль­ное хра­ни­ли­ще для кода, кото­рое реша­ет сра­зу несколь­ко задач:

  • хра­нит все вер­сии исход­но­го кода, кото­рый вы пише­те (мож­но посмот­реть, что уме­ла про­грам­ма месяч­ной дав­но­сти, и вер­нуть­ся к ней);
  • сле­дит за тем, что­бы вы не поте­ря­ли код, и поэто­му хра­нит его у себя на несколь­ких серверах;
  • поз­во­ля­ет делить­ся кодом и вме­сте рабо­тать над одним проектом;
  • помо­га­ет при­влечь новых участ­ни­ков в свой проект;
  • и вооб­ще свой акка­унт в репо­зи­то­рии — это круто!

Рабо­тать с репо­зи­то­ри­ем мож­но тре­мя способами:

  1. Мож­но писать код сра­зу там в репо­зи­то­рии через веб-интерфейс или спе­ци­аль­ное приложение.
  2. Писать код в сво­ём редак­то­ре и вруч­ную загру­жать новые фай­лы на сервер.
  3. А мож­но пору­чить это сво­ей IDE или настро­ить редак­тор кода так, что­бы он все изме­не­ния авто­ма­ти­че­ски син­хро­ни­зи­ро­вал с репо­зи­то­ри­ем. Это самый удоб­ный спо­соб рабо­ты с хранилищем.

Если у вас сго­рит ком­пью­тер, укра­дут ноут­бук или отка­жет флеш­ка с исход­ни­ка­ми — все резуль­та­ты оста­нут­ся в репо­зи­то­рии. Вы смо­же­те вос­ста­но­вить исход­ное состо­я­ние сво­е­го кода за несколь­ко минут и вер­нуть­ся к рабо­те. В шко­ле соба­ка мог­ла съесть домаш­ку, а теперь нет.

GitHub — один из самых попу­ляр­ных репо­зи­то­ри­ев. И бесплатный. 

Рабо­та с кодом в Bitbucket — в нём тоже есть бес­плат­ное хранилище. 

Совет 6. Не умничайте.

Возможно, вы слышали о существовании мероприятия под названием International Obfuscated C Code Contest – международного конкурса по самому запутанному программному коду на языке C. Все дело в том, что языки C и C++, при всех своих преимуществах, позволяют создавать кошмарно запутанный код. Этот конкурс демонстрирует преимущества понятного кода «от противного» – посредством награждения самых безумных программистов. Отличная идея.

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

Основной урок состоит в следующем. Если создаваемый код требует от вас детального знания замысловатых правил приоритета или заставляет вас заглядывать в последние главы какой-либо книги, чтобы понять, что именно вы делаете – это означает, что вы начали умничать.

Каждый программист имеет свой допустимый уровень сложности создаваемого кода. Лично я пишу свои программы так, как водит машину типичная бабушка. На мой взгляд, если ваш код на C требует понимания тонких различий между выражениями i++ и ++i, то он слишком сложен.

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

Совет 2. Используйте оператор #define чаще. КАК МОЖНО ЧАЩЕ.

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

// Мы поразили инопланетянина.
Give_player_some_points(10);

Хороший способ: В некотором глобальном файле напишите следующую строку:

#define		POINT_VALUE_FOR_ALIEN	10

Теперь, если захотим присвоить игроку несколько призовых баллов, достаточно написать следующее:

// Мы поразили инопланетянина.
Give_player_some_points(POINT_VALUE_FOR_ALIEN);

Большинство программистов так или иначе знают, что надо поступать именно так. Однако для последовательной реализации этой концепции необходима внутренняя дисциплина. Почти каждый раз, когда вы вводите числовую константу, надо тщательно обдумать – не задать ли ее в некотором «центральном пункте». Предположим, например, что вы хотите иметь игровую область с размерами 800 х 600 пикселов. Настоятельно рекомендую задавать размеры этой области следующим образом:

#define PIXEL_WIDTH_OF_PLAY_AREA	800
#define PIXEL_HEIGHT_OF_PLAY_AREA	600

Если впоследствии вы решите изменить размеры игрового окна (а это весьма вероятно), то возможность централизованного изменения этих значений сэкономит вам время дважды. Во-первых, вам не придется просматривать весь свой код в поисках всех мест, где вы указали ширину экрана, равную 800 пикселам. («800 пикселов! И о чем я только думал?») Во-вторых, вам не придется исправлять неизбежные ошибки, связанные со ссылками, которые вы неминуемо пропустите.

При работе над игрой Kill Bad Aliens мне нужно решить, сколько инопланетян необходимо убить для завершения волны, сколько инопланетян может находиться на экране одновременно и как быстро инопланетяне появляются на экране. Например, если я захочу, чтобы каждая волна имела одинаковое число инопланетян, появляющихся с одинаковой частотой, я, скорее всего, напишу что-либо подобное:

#define		NUM_ALIENS_TO_KILL_TO_END_WAVE	20
#define		MAX_ALIENS_ON_SCREEN_AT_ONCE		5
#define		SECONDS_BETWEEN_NEW_ALIENS_APPEARING	3

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

Одно из существенных преимуществ подобного механизма для задания параметров игры — такая возможность быстрого внесения изменений доставляет истинное удовольствие и позволяет чувствовать себя всемогущим. Например, вы изменили вышеприведенный текст следующим образом:

#define		NUM_ALIENS_TO_KILL_TO_END_WAVE	20
#define		MAX_ALIENS_ON_SCREEN_AT_ONCE		100
#define		SECONDS_BETWEEN_NEW_ALIENS_APPEARING	1

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

Критерии хорошего кода в программировании

Сегодня мы поговорим о том, как должен выглядеть код, для чего нужен красивый, читабельный код.

Несмотря на то, что программа исполняется машиной, программный код пишется людьми и для людей — неслучайно высокоуровневые языки программирования имеют человекопонятные синтаксис и команды. Современные программные проекты разрабатываются группами программистов, порой разделённых не только офисным пространством, но и материками и океанами. Благо, уровень развития технологий позволяет использовать навыки лучших разработчиков, вне зависимости от места нахождения их работодателей. Такой подход к разработке предъявляет серьёзные требования к качеству кода, в частности, к его читабельности и понятности.

Существует множество известных подходов к критериям качества кода, о которых рано или поздно узнаёт практически любой разработчик. Например, есть программисты, которые придерживаются принципа проектирования KISS (Keep It Simple, Stupid! — Делай это проще, тупица!). Этот метод разработки вполне справедлив и заслуживает уважения, к тому же отражает универсальное правило хорошего кода — простоту и ясность. Однако простота должна иметь границы — порядок в программе и читабельность кода не должны быть результатом упрощения. Кроме простоты, существует ещё несколько несложных правил. И они решают ряд задач.

Обеспечивать лёгкое покрытие кода тестами и отладку. Unit тестирование — это процесс тестирования модулей, то есть функций и классов, являющихся частью программы. Создавая программу, разработчик должен учитывать возможности тестирования с самого начала работы над написанием кода.
Облегчать восприятие кода и использование программы. Этому способствуют логичное именование и хороший стиль интерфейса и реализации.
Гарантировать лёгкость сопровождения. Продуманная и реализованная структура программы позволяет решать вопросы, связанные с работой программы на новом аппаратном обеспечении или новой платформе.
Упрощать процесс внесения дальнейших изменений. Чем лучше оптимизирована структура, тем проще изменять код, добавлять новые свойства, повышать быстродействие и изменять архитектуру.
Обеспечивать устойчивость программы. При внесении изменений или возможных неполадках можно легко внести исправления

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

Любой код — это реализация идей разработчика, имеющего определённую цель: создать развлечение, написать корпоративный софт, развить навыки программирования, создать промышленное ПО и проч… Важно изначально принять правила создания хорошего кода и применять их — такая привычка будет работать на программиста тем интенсивнее, чем больших масштабов будет достигать проект

Совет 5. «Преждевременная оптимизация – корень всех зол», – Дональд Кнут (Donald Knuth).

Эту фразу придумал не я. Однако она есть в Википедии, и поэтому, по всей видимости, не лишена смысла.

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

Оптимизация – враг ясности. Следует, однако, отметить, что в некоторых случаях оптимизация необходима. Это особенно справедливо для игр

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

Существуют замечательные программы этого типа. Найдите и пользуйтесь.)

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

Соблюдать это правило непросто. С другой стороны, иначе оно не было бы правилом. «Хороших» программистов неуклюжий код раздражает, даже если он работает быстрее.

Однако возрадуйтесь! После моих долгих проповедей

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

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

И, наконец, раз уж мы заговорили о болезненном, вот мой завершающий совет:

Совет 3. Не давайте переменным имена, способные ввести в заблуждение.

Конечная цель проста: написать программный код таким образом, чтобы посторонний человек, не имеющий представления о том, что этот код делает, мог понять его как можно быстрее.

Один из основных способов достижения этой цели состоит в том, чтобы давать переменным, процедурам и т.д. хорошие, т.н. «говорящие» имена. Если упомянутый выше гипотетический читатель вашего кода, посмотрев на имя переменной, подумает: «Ага, я понимаю, что это такое», это сэкономит ему пять минут – ему не придется просматривать вашу программу на предмет объяснений, что, в конце концов, по мысли автора должно означать имя .

При этом необходимо соблюдать золотую середину. Давайте своим объектам имена, достаточно длинные и наглядные для понимания их смысла, однако не настолько длинные и громоздкие, чтобы это затрудняло чтение программного кода.

Например, в реальных условиях я, скорее всего не давал бы константам такие длинные имена, которые я применил в предыдущем разделе. Я сделал это только для того, чтобы читатель смог полностью осознать их смысл без какого-либо контекста. В контексте самой программы вместо текста:

#define		MAX_ALIENS_ON_SCREEN_AT_ONCE		5

я, скорее всего, написал бы следующее:

#define		MAX_NUM_ALIENS		5

Любое недоразумение, обусловленное более коротким именем, будет устранено очень быстро, а «читаемость» кода улучшится.

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

// Переместить всех инопланетян
for (short i  = 0; I < MAX_NUM_ALIENS; i++)
	if (aliens.exists()) // Существует ли этот инопланетянин 
	                        // в данный момент времени?
		aliens.move_it();

Обратите внимание, что массив для всех инопланетян так и называется –. И это очень хорошо

Данное имя передает именно то, что я хотел сказать, однако при этом оно достаточно короткое, чтобы я мог ввести его с клавиатуры тысячи раз и не сойти при этом с ума. По всей вероятности, вы будете использовать этот массив ОЧЕНЬ ЧАСТО. Если вы назовете этот массив , ваш программный код станет на десять миль длиннее и настолько же непонятнее.

Кроме того, параметру цикла я без каких-либо дополнительных комментариев дал простое имя . Если вы только начали осваивать стратегию описательного именования переменных, у вас может возникнуть искушение дать этой переменной «говорящее» имя counter (счетчик) или что-то вроде этого. Это совсем не обязательно. Цель именования переменной состоит в том, чтобы немедленно вызвать у читателя реакцию: «Ага, я знаю, что это значит». Если я дам этой переменной имя i, j и т.д., любой читатель сразу поймет, что это параметр цикла. Каких-либо дополнительных разъяснений не требуется.

Несомненно, к именованию переменных можно относиться гораздо серьезнее. Например, существует т.н. венгерская нотация. Эта концепция имеет множество вариантов, однако ее основная идея состоит в том, что каждое имя переменной должно начинаться с префикса, указывающего на тип этой переменной. (Например, все переменные типа unsigned long variable должны начинаться с префикса и т.д.). На мой взгляд, это уже перебор, однако вам надо знать о существовании и такого варианта. Можно потратить достаточно много времени на то, чтобы сделать вещи понятнее, однако решение этой задачи также требует определенных усилий.

Сервис совместной работы

Класс­ные про­дук­ты полу­ча­ют­ся у тех, кто нахо­дит себе еди­но­мыш­лен­ни­ков и рабо­та­ет над про­ек­том вме­сте. Что­бы делать это быст­рее и про­ще, чем сидеть рядом за одним ноут­бу­ком, исполь­зуй­те соци­аль­ные сервисы.

Они уме­ют такое:

  • орга­ни­зо­вы­вать рабо­ту в коман­де и выстра­и­вать иерархию;
  • рабо­тать с комментариями;
  • при­ни­мать или откло­нять прав­ки дру­гих программистов;
  • вести логи проекта;
  • созда­вать закры­тые груп­пы для обсуждений;
  • при­гла­шать внеш­них поль­зо­ва­те­лей как гостей для кон­суль­та­ций по проектам.

Slack — ско­рее все­го, вы про него уже слы­ша­ли. В неко­то­рых отрас­лях это стан­дарт­ная рабо­чая среда. 

Gitter — про­дукт для сов­мест­ной рабо­ты над про­ек­том от вла­дель­цев GitHub. 

Совет 4. Проверяйте свою программу на наличие ошибок. Вы ведь делаете ошибки. Да-да, именно вы.

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

При создании любой процедуры/функции всегда нужно задаваться вопросом: «Предположим, некий невменяемый злодей передаст в нее самые неподходящие значения. Как этот мягкий и пушистый кусочек кода сможет защитить себя и сохранить всю программу от повреждения?» Затем напишите свой код так, чтобы он проверял эту процедуру/функцию на наличие таких враждебных данных и защищался от них.

Рассмотрим следующий пример. Основная задача нашей замечательной космической игры состоит в том, чтобы убивать инопланетян и набирать баллы, поэтому нам необходима процедура для изменения набранных игроком баллов. Более того, при добавлении игроку баллов мы хотели бы вызывать процедуру, которая расцвечивала бы итоговый счет красивыми искорками. Первый вариант выглядит следующим образом:

Void change_score(short num_points)
{
	score += num_points;

	make_sparkles_on_score();
}

Пока все идет нормально. Теперь задайте себе вопрос: «Что в этом коде может быть не так?»

Во-первых, один очевидный момент. Что произойдет, если переменная будет иметь отрицательное значение? Можем ли мы допустить, чтобы счет игрока снижался? Возможно. Однако в описании игры я до этого нигде не упоминал о возможности потери игроком баллов. Кроме того, игры должны приносить удовольствие, а потеря баллов этому противоречит. Таким образом, мы приходим к выводу, что отрицательное число очков – это ошибка, которую необходимо поймать.

Этот пример был достаточно простым. Существует и менее очевидная проблема (с которой я постоянно сталкиваюсь в своих играх). Что произойдет, если переменная будет равна нулю?

Это весьма правдоподобная ситуация. Не забудьте, что по окончании каждой волны мы даем игроку бонусные баллы в зависимости от скорости ее прохождения. Что произойдет, если игрок будет действовать слишком медленно и мы решим дать ему 0 баллов? Вполне вероятно, что, работая над своим кодом в 3 часа ночи, вы решите вызвать процедуру и передать ей значение 0.

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

Void change_score(short num_points)
{
	if (num_points < 0)
	{
		// Возможно появления сообщения о какой-либо ошибке
		return;
	}

	score += num_points;

	if (num_points > 0)
		make_sparkles_on_score();
}

Ну вот. Так гораздо лучше.

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

Если вы передаете массивы или указатели, вам ОБЯЗАТЕЛЬНО нужно предусмотреть выявление ошибок или плохих данных.

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

Этот подход экономит массу времени и заслуживает регулярного применения. Время – наш самый ценный ресурс.

Как научиться?

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

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

Вполне вероятно, что задача, с которой вы столкнулись, уже решена и это решение где-то лежит. Иногда разобраться с тем, как оно работает, сложнее, чем написать заново. Это стандартная программистская проблема, но для этого у нас есть Stack Overflow, одно из главных изобретений человечества в сфере программирования. Это сайт, где разработчики делятся опытом и отвечают на вопросы друг друга. У каждого участника свой уровень репутации, все очень удачно спроектировано, поэтому на простые вопросы можно получить ответ в течение десяти секунд. Это очень помогает. В современном мире вы не просто пишете программу — вы одновременно используете огромное количество программ и инструментов, уже созданных другими людьми.

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

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

Если вы только учитесь программированию, не нужно сразу пытаться писать много кода до тех пор, пока вы не сможете корректно объяснять, чего хотите. Это нужно для того, чтобы компьютер выполнял команды четко и маленькими шажками. Всякий раз ваши эксперименты должны заканчиваться не тем, что вы случайно наткнулись на правильное решение, а пониманием, почему и как это работает.

Не беспокойтесь по поводу математики. Желательно знать, что такое остаток от деления числа на другое число, но все зависит от задач, которые перед вами стоят. Конечно, если вы хотите хитро обрабатывать данные, то вам нужна математика в том объеме, который нужен для такой обработки.

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

Есть мнение, что на фоне развития искусственного интеллекта и машинного обучения программисты скоро будут не нужны: компьютеры сами научатся себя программировать. Но мне кажется, что это не так. До тех пор, пока есть задачи и пока нужно объяснять, как их решать, программирование будет существовать. Безусловно, программирование сильно эволюционирует, за последние 20 лет оно изменилось очень сильно. Но от того, что компьютеры стали умнее, разработчиков меньше не стало — наоборот, их стало гораздо больше. И мне кажется, что дальше будет происходить то же самое.

Совет 1. Будьте благоразумны – пишите комментарии.

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

Следует, однако, отметить, что написание комментариев – это тоже искусство. Для достижения мастерства в этом виде деятельности необходима практика. Комментарии бывают хорошие и плохие.

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

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

И, наконец, не следует писать глупых комментариев. Когда человек впервые приступает к написанию комментариев, он часто выпендривается и пишет что-либо вроде:

// Теперь мы увеличиваем значение Number_aliens_on_screen на единицу.
Number_aliens_on_screen = Number_aliens_on_screen + 1;

И уж если мы подошли к этому, еще одна рекомендация – никогда не делайте такого:

Short get_current_score()
{
	

	return ;

	// Теперь мы сделали все, что хотели.
}

Ну и что? Мы закончили? Спасибо, что сообщили мне об этом. Эти квадратные скобки и фактически пустое пространство между ними не несут никакой полезной для меня информации. Кроме того, перед оператором возврата нет необходимости вставлять комментарии вида «Теперь мы возвращаем значение».

Итак, как комментировать свою программу, если вы пишете программный код в отсутствие указаний начальника или корпоративных правил? Что касается меня, то первое, что я делаю при написании программного кода, который мне придется поддерживать самому – пишу введение. Когда я возвращаюсь к созданной ранее процедуре, я уже давно забыл, о чем думал в момент ее написания, поэтому мне хочется понять, что эта процедура делает. После того как я пойму, что программа делает, становится значительно проще понять реальный программный код. В общем случае необходимы следующие комментарии:

  1. Несколько предложений в начале процедуры/функции, объясняющих, что она делает.
  2. Описание значений, передаваемых в эту процедуру/функцию.
  3. В случае функции — описание смысла возвращаемых параметров.
  4. Внутри процедуры/функции – комментарии, разбивающие программный код на короткие подзадачи.
  5. Для особо сложных фрагментов кода – краткое пояснение того, что происходит.

Итак, все, что нам необходимо – это описание в начале и несколько «указателей» внутри, поясняющих выбранный путь. Все это делается очень быстро и в длительной перспективе экономит массу времени.

Ниже приведен пример из нашей гипотетической игры Kill Bad Aliens. Рассмотрим объект, представляющий снаряды, которыми стреляет игрок. Вам придется часто вызывать функцию, которая будет перемещать этот объект вверх и определять, куда он попал. Я бы написал эту процедуру примерно так:

// Данная процедура перемещает снаряд вверх. Вызов этой процедуры 
// осуществляется NUM_BULLET_MOVES_PER_SECOND раз в секунду. Она 
// возвращает значение TRUE, если снаряд подлежит стиранию (поскольку 
// он поразил цель или попал в верхнюю часть экрана) или значение 
// FALSE в противном случае.
Boolean player_bullet::move_it()
{
	Boolean is_destroyed = FALSE;

	// Вычислить новое положение снаряда.

	

	// Проверить, не находится ли противник в новом положении. Если да, 
	// то вызвать процедуру уничтожения противника и присвоить 
	// переменной is_destroyed значение TRUE

	

	// Проверить, не попал ли снаряд в верхнюю часть экрана. Если да, 
	// то присвоить переменной is_destroyed значение TRUE

	

	// Изменить положение снаряда.

	

	Return is_destroyed;
}

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

Программа оценки качества кода

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

Такие про­грам­мы назы­ва­ют­ся лин­те­ра­ми. Lint — это по-английски катыш­ки, мел­кие сгуст­ки шер­сти на тка­ни, кото­рые надо удалять.

Для каж­до­го язы­ка — свой лин­тер. Ино­гда их мож­но встро­ить сра­зу в редак­тор или IDE. Если так сде­лать, раз­ра­бот­ка пой­дёт быстрее.

JSLint — сер­вис про­вер­ки JavaScript-кода. 

Pep8 про­ве­ря­ет код на Питоне. У это­го сер­ви­са есть свой API, а зна­чит, его мож­но под­клю­чить к редак­то­ру напрямую. 

Заключение

Возможно, дочитав до этого места, вы думаете: «И это все? Только зря потратил время. Это же очевидно и всем известно. Зачем автор все это писал?» Очень надеюсь, что вы думаете именно так. Значит, вы уже сами все знаете. Очень рад за вас.

Однако не надо думать, что все изложенное очевидно каждому. На самом деле это не так. Плохо написанный программный код появляется снова и снова – хотя без этого можно было бы обойтись.

Если вы имеете дело с огромными объемами программного кода и не хотите погибнуть под его грузом, я искренне надеюсь, что мои советы вам помогут. Стремитесь к простоте и ясности – это сбережет вам массу времени и избавит от ненужных страданий.

Похожие темы

Оригинал статьи
Six ways to write more comprehensible code: How to keep your code from destroying you.

Различные варианты венгерской нотацииописаны в Википедии.
Обратите внимание на
профайлеры, перечисленные в Википедии. Как правило, для каждой среды разработки требуется свой профайлер

Изучение документации по вашей среде разработки поможет найти подходящий вариант.
Если вы любитель неподдерживаемого программного кода, рекомендую ознакомиться с победителями конкурса International Obfuscated C Code Contest.
Рекомендую также ознакомиться с другими советами по написанию удобного для поддержки программного кода: 9 советов от Брэма Кохена (Bram Cohen) (how to write maintainable code), 6 советов от Шона Келли (Sean Kelly) (more maintainable code) и 12 советов от Джоэла Сполски (Joel Spolsky) (12 steps to better code).
Примерно 100 иронических антисоветовв прекрасной работе Руди Грина (Roedy Green) «Как написать неподдерживаемый программный код» (юмористическая статья).
Ознакомьтесь с играми от автора статьи, и вы увидите его мудрость в ее реальном воплощении.
Ознакомьтесь с избранными работами автора, включая юмористические заметки, статьи по компьютерным играм и различные технические материалы.
В разделе Linux сайта developerWorks можно найти дополнительные ресурсы для Linux-разработчиков, включая руководства по Linux, а также самые популярные среди наших читателей статьи и руководства по Linux за последний месяц.
Используйте ознакомительные версии программных продуктов IBM, которые можно загрузить непосредственно с сайта developerWorks, в своем следующем проекте по разработке для Linux.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector