Что такое компьютерный код
В предыдущей части мы затронули азы программирования, где рассказали о машинном языке, преобразователях, языках программирования и работе с CLI. Двигаемся дальше.
Исходным кодом называется основной файл вроде Microsoft (.doc), но немного другой. Это текстовый файл, написанный с помощью простых редакторов, таких как Windows Блокнот. В предыдущем разделе мы перечислили, что нужно, чтобы интерпретаторы или компиляторы конвертировали исходный код в двоичный. Первый должен быть сохранен в файле, что передается для ввода в переводчик (преобразователь).
В зависимости от выбранного языка, есть назначенные расширения для сохранения файла: Python – .py. Java – .java. PHP – .php, PERL – .pl и т. д.
Когда вы закончите писать код, запустите его через переводчик. Рассмотрим в качестве примера запуск кода на языке Python с использованием команды python.
Начало работы: ваша первая программа
- Следуйте приведенным здесь инструкциям, чтобы настроить Python в вашей компьютерной системе.
- Установите простой редактор, чтобы ввести исходный код. Для начала можете использовать этот текстовый редактор.
3. Откройте в нем новый файл и введите следующее:
- Не забудьте сохранить файл как main.py.
- Найдите путь к файлу через CLI и введите следующую команду:
Результат должен выглядеть так:
Анатомия типичного кода
Теперь мы рассмотрим содержимое типичного файла исходного кода. Ниже приведены регулярные компоненты.
Ключевые слова
Короткие человекочитаемые слова, обычно называемые ключевыми. Они свойственны изучаемому вами языку и они особенны. Их просто нужно знать. Вот небольшой набор ключевых слов, часто используемых в Python.
Идентификаторы
Слова, изобретенные вами. Да, не удивляйтесь! Вы, программист. Эти слова обычно называются идентификаторами. Они могут быть созданы вами или другими программистами. Они упакованы в плагины, более известные как библиотеки.
Примером является библиотека Math. Она позволяет получить доступ к функциям, таким как квадратный корень (Math.sqrt), используемый в JavaScript.
Многие языки программирования поставляются со множеством библиотек. Они обычно называются SDK (комплекты разработки программного обеспечения). Загружаются вместе с компилятором для дальнейшего создания технологий, приложений и проектов. Также существуют фреймворки, созданные, чтобы облегчить разработку проекта и объединить его различные составляющие.
Некоторые идентификаторы в комплекте с выбранным языком не могут использоваться в качестве идентификатора пользователя. Примером является слово string в Java. Такие идентификаторы вместе с ключевыми словами называются Зарезервированными Словами. Они также являются особыми.
Все ключевые слова являются зарезервированными. Также слова, которые вы выбираете, должны иметь смысл для тех, кто впервые их видит.
Основные типы данных
Исходный код – сосредоточение разных типов даннх: числа (3, 5.7, -100, 3.142) и символы (M, A). В некоторых языках программирования числа разбиваются на подтипы, такие как integers (целые числа).
Целые числа могут быть знаковыми и беззнаковыми, большими и малыми. Последние фактически зависят от объема памяти, зарезервированного для таких чисел. Есть числа с десятичными частями, обычно называемые double и float, в зависимости от языка, который вы изучаете.
Также существуют логические типы данных boolean, которые имеют значение true или false.
Сложные типы данных
Указанные выше типы известны как элементарные, первичные или базовые. Мы можем создавать более сложные типы данных из приведенных базовых.
Массив (Array) – это простейшая форма сложного типа. Строка (String) – это массив символов. Мы не можем обойтись без этих данных и часто используем их при написании кода.
Комбинация символов – это строка. Чтобы использовать аналогию, строка для компьютера означает, что слово принадлежит человеку. Слово «термометр» состоит из 9 символов – мы просто называем это строкой символов. Обработка строк – это обширная тема, которая должна изучаться каждым начинающим программистом.
Сложные типы данных поставляются с большинством языков программирования, которые используются. Есть и другие, такие как системы классов. Это явление также известно как объектно-ориентированное программирование (ООП).
Переменные
Переменные – это просто имена областей памяти. Иногда нужно сохранить данные в исходном коде в месте, откуда их можно вызвать, чтобы использовать. Обычно это место памяти, которое резервирует компилятор/интерпретатор. Нам нужно дать имя этим ячейкам памяти, чтобы потом их вспомнить. Рассмотрим фрагмент кода Python ниже:
pet_name – пример переменной, и тип данных, хранящихся в pet_name, является строкой, что делает переменную строковой. Существуют также числовые. Таким образом, переменные классифицируются по типам данных.
Константы
Константы – это значения, которые не изменяются на протяжении всего жизненного цикла программы. Чаще всего в их именах используются заглавные буквы. Некоторые языки поддерживают создание постоянных значений, а некоторые – нет.
Существуют строго типизированные языки программирования, в которых каждая переменная должна быть определенного типа. Выбрав тип один раз, вы больше не сможете его изменить. Java – хороший пример такого ЯП.
Другие же не предоставляют эти функции. Они являются свободно типизированными или динамическими языками программирования. Пример – Python.
Вот как объявить постоянное значение в JavaScript:
Литералы
В каждом исходном коде существуют типы данных, которые используются повсюду и изменяются только в том случае, если их отредактировали. Это литералы, которые не следует путать с переменными или константами. Ни один исходный код не обходится без них. Литералы могут быть строками, числами, десятичными знаками или любыми другими типами данных.
В приведенном выше фрагменте слово «Hippo» является строковым литералом. Это всегда будет «Hippo», пока вы не отредактируете исходный код. Когда вы научитесь кодить, узнаете, как управлять литералами таким образом, чтобы оставлять неизменной большую часть кода.
Пунктуация/Символы
В большинстве написанных программ вы найдете различные знаки препинания в зависимости от выбранного языка программирования. Например, в Java используется больше знаков препинания, чем в Python.
Основные знаки включают в себя запятую (,), точку с запятой (;), двоеточие (:), фигурные скобки (<>), обычные круглые скобки (()), квадратные скобки ([]), кавычки ("" или ''), вертикальную черту (|), слэш (\), точку (.), знак вопроса (?), карет (^) и процент (%).
Операторы
Шансы, что вы будете писать исходный код для выполнения какой-нибудь операции, крайне высоки. Любые языки программирования, которые мы используем, включают в себя множество операторов. Среди применяемых выделяют сложение (+), деление (/) умножение (*), вычитание (-) и знак больше (>).
Операторы обычно классифицируются следующим образом:
- Операторы присваивания. Они иногда истолковываются как equals, что неправильно. Равенство используется для сравнения двух значений. А вот оператор присваивания присваивает значение переменной, например pet_name = 'Hippo'
- Арифметические операторы. Состоят из операторов для выполнения арифметических задач, таких как сложение и вычитание. Некоторые языки программирования предоставляют арифметические операторы, когда другие могут их не иметь в своем арсенале. Например, оператор модуля/остатка (%) возвращает остаточное значение в операциях деления.
- Реляционные операторы. Используются для сравнения значений. Они включают в себя больше, меньше, равно, не равно. Их представление также зависит от того, какой язык программирования вы изучаете. Для некоторых ЯП не равно – это <>, для других же – != или !==.
- Логические операторы. Применяются для произведения логических операций. Обычно используемыми логическими операторами являются и, или, нет. Некоторые языки представляют эти операторы в виде специальных символов. Например, && для представления логического и, || – для или, и ! – для нет. Логические значения принято оценивать с помощью булевых значений true или false.
Комментарии
Документация будет важным аспектом деятельности в сфере программирования. Это то, как вы объясняете свой код другим программистам. Подобное делается с помощью комментариев, которые добавляются к различным частям кода. С помощью комментариев вы можете направлять других программистов через написанную программу.
Компилятор игнорирует строки кода, которые являются комментариями.
Вот пример комментария в Python:
Пробелы и вкладки
Это пробелы, созданные между кодом, который вы пишете. Они ставятся при нажатии пробела или клавиши табуляции на клавиатуре.
Двигаемся дальше
Вы познакомились с исходным кодом и изучили его содержимое. Скомпилированный или преобразованный код может не запускаться по ряду причин. Эти причины обычно связаны с ошибками. Действие поиска и удаления ошибок называется отладкой и является навыком, который вы должны изучить. Ошибки мы рассмотрим в следующей части.
Убедитесь, что вы правильно настроили Python в своей компьютерной системе, и запустите свою первую программу.
Викторина
Определите элементы, которые мы изучили, в приведенном ниже фрагменте кода Java:
Статья разделена на 4 части. Обратите внимание, что важные слова или словосочетания, введенные в этой серии, выделены жирным шрифтом. В конце каждого из четырех разделов будет приведена короткая викторина, проверяющая знания и подробно объясняющая некоторые моменты.
Самый простой и точный вариант ответа: «Программирование – это акт инструктирования компьютеров для выполнения задач». Еще его называют разработкой или кодингом.
Итак, что такое компьютерная программа? ПО представляет собой последовательность инструкций, выполняемых ПК. Компьютер же – это любое устройство, способное обрабатывать код. Сюда относятся стационарные ПК, ноутбуки, планшеты, банкоматы, Raspberry Pi, серверы etc.
Разработка программного обеспечения и аналогия
Во-первых, примеры программирования есть даже в повседневной жизни. Вселенная довольно предсказуема: день и ночь, времена года, восход и закат. Люди проходят через такие этапы, как встреча нового дня, посещение школы, университета или работа. Мы получаем инструкции от начальников и учителей. Также существуют рецепты, следуя которым можно приготовить блюдо.
Во-вторых, каждый раз, когда мы используем девайсы, встроенный в них код уже работает в фоновом режиме. Перемещение курсора с одной части экрана в другую может показаться простой задачей, но на самом деле за данный процесс отвечает немало строк написанного кода. Акт, столь же простой, как ввод букв в Google Docs, приводит к тому, что код выполняется в фоновом режиме. Это нормальные повседневные процессы, свойственные всем IT-устройствам.
Компьютерные программы также являются кодом. Однако лучше не использовать слово «коды»: это непрофессионально.
Естественный язык компьютера
Машины пользуются своим собственным языком. Они не понимают русский, английский или испанский. Естественным языком электронного оборудования является двоичный код - 1 и 0. Он представляют собой два состояния: on (1), off (0).
Осваивайте языки программирования
Чтобы общаться с машинами, которые говорят на двоичном языке, мы осваиваем такие языки, которые максимально близки к нашему собственному, а именно – языки программирования. Они четко структурированы и должны быть тщательно изучены.
Существуют высокий и низкий уровни. Языки программирования высокого уровня находятся дальше от машинного, чем языки низкого уровня. Это «дальше» обычно называют абстракцией.
Компьютер нуждается в понимании нашего человеческого языка. Для этого понадобится переводчик.
Определение переводчиков
Исходный код относится к коду, написанному на выбранном языке программирования. Переводчики же несут ответственность за преобразование исходного кода в машинный язык (те самые единицы и нули). Мы можем ссылаться на двоичные файлы, такие как код объекта, программу или общепринятый сегодня термин – приложение.
Переводчики могут быть любыми:
- интерпретаторы;
- компиляторы;
- гибриды интерпретаторов и компиляторов;
- ассемблеры.
Интерпретаторы
Чтобы разработка программного обеспечения прошла успешно, нужно понимать, что языки могут интерпретироваться. В таком случае переводчик обрабатывает исходный код по строкам и в готовой программе (приложении) также запускает каждую строку. Это означает, что интерпретируемый исходный код запускается до тех пор, пока не встретит ошибку. Затем интерпретатор перестает сообщать о таких ошибках.
Python – хороший пример интерпретируемого языка программирования.
Компиляторы
Компиляторы работают по-разному. Они полностью конвертируют исходный код с помощью компиляции в двоичный файл. Затем выполняется двоичный код. Если в исходном варианте были ошибки, они обнаруживаются и помечаются во время компиляции. Это прерывает процесс генерации двоичного кода.
Интерпретаторы работают построчно и выполняют одну линию перед тем, как перейти к следующей. Компилятор же переводит все строки программы в файл (двоичный) и выполняет его целиком.
Помните определение компьютерной программы? Это последовательность инструкций для компьютера. Выполнение программы обычно называется процессом. Такие ПО используют определенные ресурсы в компьютерной системе или любом другом девайсе. К ресурсам относятся память, дисковое пространство и файловая система.
Мы используем слово «run» при выполнении компьютерной программы. Время, затрачиваемое на запуск, называется временем выполнения программы.
Обычно рассматриваются продукты, известные как приложения. Еще мы ассоциируем программы с платформами или средами, в которых они работают или для которых предназначены. Существуют веб-приложения, запускаемые в браузерах, есть мобильные ПО, работающие на смартфонах, а также настольные, такие как Evernote.
Интерпретируемый исходный код выполняется из исходного файла, скомпилированный – преобразовывается в двоичный файл. Затем этот файл выполняется. Скомпилированный код может завершиться неудачно во время выполнения даже после успешной компиляции.
Гибридные переводчики
Гибридный переводчик представляет собой комбинацию интерпретатора и компилятора. Популярным гибридным языком программирования является Java.
Разработка программного обеспечения на Java удобна. Сначала исходный код компилируется в промежуточный формат, известный как Bytecode. Затем Bytecode интерпретируется и выполняется с помощью виртуальной машины. Это позволяет гибридным переводчикам запускать байт-код в различных операционных системах, делать его кроссплатформенным.
Ассемблеры
Ассемблер также используется для перевода низкоуровневого языка Ассемблер в двоичный, но мы сосредоточимся на языках высокого уровня.
Хороший способ понять различия переводчиков – лично увидеть их работу. Просто загрузите необходимые и установите на компьютер.
Часто задаваемый вопрос
Вот вопрос, который обычно задают начинающие: «С какого языка начать?»
Существуют сотни ЯП. Они оцениваются по популярности, комьюнити, долгосрочной поддержке, педагогике и использованию. Они также могут быть оценены по техническим параметрам. Например, являются ли они функциональными, императивными, статическими, сильными или слабо типизированными.
Некоторые языки программирования предназначены исключительно для образовательных целей, а не для использования в бизнесе. Хороший пример – ЯП для детей. Также существуют мощные языки, которые легко настроить и изучить. Python – один из них. Обычно его и рекомендуют начинающим.
Если вы заинтересованы в более подробном изучении вопроса, вот несколько хороших исследований.
Когда вы захотите изучить новый язык, понадобится переводчик языка. Это программа, которая устанавливается и настраивается в компьютерной системе.
Рекомендуем начать осваивать работу с командной строкой (CLI). Подумайте о терминале как об альтернативе графическому интерфейсу (GUI). Работая с компьютером посредством GUI, вы зависите от визуальных представлений каталогов и всего, что делаете. Но при использовании CLI вы взаимодействуете с компьютером напрямую, с помощью терминала и специальных команд.
В Windows встроенный терминал представляет собой командную строку. Для пользователей Mac и Linux по умолчанию установлен терминал Bash. Чтобы использовать его в Windows, установите Git Bash или PowerShell.
Двигаемся дальше
Приготовьтесь, ведь разработка программного обеспечения началась! Подготовимся к написанию первой строки кода. Для этого потребуется следующее:
- Компьютерная система. Необязательно сложный или очень дорогой ПК. Подойдет просто компьютер, который хорошо работает.
- Установка CLI. Вот хороший курс для начала работы.
- Установка текстового редактора (например, Notepad++).
- Понимание хотя бы одного языка программирования. Из статьи вы узнаете основные элементы, которые составляют фундамент большинства ЯП.
Резюмируя вышесказанное, мы изучили основы с введением в переводчики. Слово «исходный код» уже не странно для вас. Более подробно мы рассмотрим его дальше.
Программисты в первую очередь работают с языком. Поэтому написание программ похоже на любой другой вид письменной работы. Сначала вы излагаете свои мысли как есть, а затем «причесываете» до тех пор, пока текст не будет легко читаться. Качество кода – результат проявления небезразличного отношения к делу и показатель профессионализма.
Сначала учимся читать и писать код, потом читать и переписывать написанный другимиЧтение кода происходит чаще, чем написание. Есть большая разница между обучением программированию и реальной работой в компании. Вначале мы и пишем, и читаем собственные программы. Но чем дальше мы продвигаемся, тем чаще нам приходится не писать, а читать код. Чем легче код читается, тем проще с ним работать другим людям.
Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живетеЧем проще читать код, тем проще его сопровождать. Понятный, читаемый код легче тестировать, в нем легче отлавливать ошибки – они не скрываются в его запутанной структуре. Плохо оформленный код неприятно изучать, читать, тестировать, сложно дополнять. Рано или поздно плохой код становится проще переписать.
Эстетическое восприятие кода влияет на удобство работы. Казалось бы, гораздо важнее производительность, возможность модификации, расширения… Но все эти показатели улучшаются, если код соответствует нашему чувству прекрасного. Глядя на качественно написанный код, можно быстро понять алгоритм и то, как работает программа для разных входных данных. Чистый код читается, как хорошо написанная проза: слова превращаются в зрительные образы.
Стиль кода определяет его будущее. Стиль и дисциплина продолжают жить в коде, даже если в нем не осталось ни одной исходной строки.
Все дороги программиста ведут к документации. В каждом языке существует свой стандарт оформления кода. Для Python используется документ PEP-8, для PHP – стандартные рекомендации PSR-1 и PSR-2, для Java – Java Coding Conventions, для JavaScript – Airbnb JavaScript Style Guide или Google JavaScript Style Guide. Документ для вашего языка вы найдете по поисковому запросу <Название языка> Code Style.
Когда вы работаете в группе разработчиков, нужно использовать принятые в команде правила. Стиль должен быть единым, как будто код был написан одним здравомысленным человеком.
В популярных IDE заложена возможность автоматической настройки стиля кода под стандарты – общие или предложенные командой. Разберитесь, как настроить среду под необходимое оформление. Потраченное время сэкономит многие часы рутинной работы.
Применение стандартов – лучший подход для новичка. Читающий не будет отвлекаться на оформление и сразу погрузится в тонкости выбранных подходов, а не расстановок переносов. Изложенные ниже правила понадобятся для того, чтобы понять, как действовать в тех случаях, когда стандарт не дает никаких рекомендаций.
Как Библиотека программиста, мы не могли обойтись без упоминания замечательной книги Роберта Мартина о чистом коде и анализе программ. В книге приводятся примеры для языка Java, но большинство идей справедливы для любых языков.
Если вы видели эту книгу ранее с другим оформлением, не удивляйтесь – это новая версия обложки книги «Чистый код»
Всё что изложено ниже, в значительной мере представляет сжатый конспект этой книги с дополнениями из нашего опыта в проектировании программ. Итак, приступим к практикам.
Содержательность. К выбору названий любых объектов нужно подходить со всей ответственностью. Выразительные имена позволяют писать код, не требующий комментариев.
Полезно не только исходно выбирать ясные имена, но и заменять названия на более удачные, если они нашлись позже. Современные среды программирования позволяют легко заменить название переменной во всём коде, так что это не должно быть проблемой.
В первом примере непонятно, что вообще происходит, хотя в этом коде нет ни сложных выражений, ни каких-либо странностей. В результате правок сам код никак не изменился. Если знать, что это часть игры «Сапер», то теперь из кода понятно: здесь обрабатывается список ячеек игрового поля. Этот код можно улучшать и далее, но уже в результате простого переименования переменных стало понятно, что происходит.
Избегайте любых двусмысленностей и ложных ассоциаций. Если в объекте перечисляется список, но сам объект не является списком, нельзя в составе его названия употреблять слово list – это запутывает читающего.
Остерегайтесь малозаметных различий – имена объектов должны существенно отличаться друг от друга. По этой причине плохи длинные имена с повторяющимся элементами – чтобы сличить их друг с другом, тратятся лишние силы и время. Избегайте использования в именах переменных строчной буквы L и прописных I, O – они часто путаются с единицей и нулем.
Путаница также возникает, если несколько синонимичных слов и выражений используются для обозначениях разных сущностей, например, controller , manager и driver .
Имя должно легко произноситься. Используйте для названий слова. Если названия состоят из сокращений, каждый начинает произносить их по-своему, что затрудняет взаимопонимание. А при чтении кода каждый раз «спотыкаешься» о такое название.
Имя должно быть удобным для поиска. Слишком короткие имена трудно искать в большом объеме текста. Однобуквенные имена можно использовать только для локальных переменных в коротких методах и для счетчиков циклов ( i, j, k ). Обычно называя объект одной буквой, вы всего лишь создаете временный заменитель. Но не бывает ничего более постоянного, чем что-то «временное». Проверяйте грамотность написания выбранных слов.
Правильно выбирайте часть речи. Классы и объекты желательно называть существительными и их комбинациями: Account , WikiPage , HTMLParser . Имена функций и методов лучше представлять глаголами или глагольными словосочетаниями: delete_page , writeField(name) . Для методов чтения/записи и предикатов используйте стандартные префиксы get , set , is .
Заменяйте «магические» числа именованными константами. Одно из самых древних правил разработки. Магическими называют числа, о которых сходу нельзя сказать, что они означают. Например: 100 , 1.1 , 42 , 1000000 . Выделяйте такие числа в соответствующие константы с конкретным названиями. Например, вместо числа 86400 в теле кода приятнее встретить константу SECONDS_PER_DAY .
Не стоит следовать этому правилу, как и любому другому, безоговорочно. В формулах некоторые константы лучше воспринимаются в числовой записи.
Одно слово для каждой концепции. Для одной и той же идеи, реализующей одну механику, используйте одно слово. Например, для добавления элементов одинаковым образом – метод add . Однако, если механика и семантика изменились, потребуется и другое слово (например, insert , append ), описывающее новую концепцию.
Ваш код будут читать программисты. Не стесняйтесь использовать термины из области информатики, общепринятые названия алгоритмов и паттернов. Такие имена сообщают информацию быстрее, чем сам код.
Помещайте имена в соответствующий контекст. Например, имена street , house_number , city понятнее смотрятся внутри класса Address .
Избегайте остроумия и каламбуров в названиях. Шутки имеют свойство быть понятными лишь ограниченное время и для конкретной аудитории, знакомой с первоисточником. Отдавайте предпочтение ясности перед развлекательностью. Шутки можно приберечь для презентации, которая происходит «здесь и сейчас». Хороший код способен выйти далеко за границы вашей культуры.
Среды разработки продолжают развиваться. Уже нет никакой необходимости кодировать типы в именах, создавать префиксы для членов классов. Всю нужную информацию можно получить из цветового выделения или контекстно-зависимых подсказок сред разработки. Добавление префиксов убивает удобство поиска по автодополнению – выпадает слишком много имен, начинающихся с одинаковых символов.
Компактность. Уже в 80-е годы считалось, что функция должна занимать не более одного экрана. Экраны VT100 состояли из 24 строк и 80 столбцов. В наши дни на экране можно разместить гораздо больше инфорфмации, но лучше ограничиться тем же объемом. Самоограничение позволяет видеть точку объявления каждой используемой переменной и держать в уме всю «историю», которую рассказывает функция.
Внешний вид текстового компьютерного терминала VT100
Вполне вероятно, что тот, кто будет сопровождать ваш код, не будет иметь возможности работать на большом мониторе. Например, ему необходимо одновременно разместить на одном рабочем столе экрана ноутбука несколько окон. Среды разработки позволяют установить ограничение, «верхнюю планку» (то есть правую 😉 ).
Блоки if, else, while должны иметь минимальный размер, чтобы информацию о них можно было держать в уме. Старайтесь избегать отрицательных условий – на их восприятие обычно уходит чуть больше времени, чем на положительные. То есть запись if (buffer.shouldCompact()) предпочтительнее записи if (!buffer.shouldNotCompact() .
Правило одной операции. Плохой код пытается сделать слишком много всего, намерения программиста расплываются для читателя. Поэтому стоит ввести важное правило:
Функция должна выполнять только одну операцию, выполнять ее хорошо, и ничего другого она делать не должна.Каждая функция должна делать то, что вы от нее ожидали из названия. Если функция действует не так, как она названа, читатель кода перестает доверять автору программы, ему приходится самостоятельно разбираться во всех подробностях реализации.
Я люблю, чтобы мой код был элегантным и эффективным. Логика должны быть достаточно прямолинейной, чтобы ошибкам было трудно спрятаться; зависимости — минимальными, чтобы упростить сопровождение; обработка ошибок — полной в соответствии с выработанной стратегией; а производительность — близкой к оптимальной, чтобы не искушать людей загрязнять код беспринципными оптимизациями. Чистый код хорошо решает одну задачу.Исключения вместо кодов ошибок. Используйте исключения ( try-catch , try-except ) вместо возвращения кодов ошибок. Возвращение кодов приводит к слишком глубокой вложенности.
Соблюдайте уровни абстракции. Одна функция – один уровень абстракции. Смешение уровней абстракции создает путаницу, функция обрастает слишком большим количеством второстепенных подробностей. Старайтесь соблюдать ясную иерархию.
Код читается сверху вниз. По мере чтения уровни абстракции должны меняться равномерно. Каждая функция должна быть окружена функциями единого уровня абстракции.
Ограничивайте число аргументов. Чем больше аргументов у функции, тем сложнее с ней работать. Необходимость функций с количеством аргументов большим двух должна быть подкреплена очень вескими доводами. Каждый новый аргумент критически усложняет процедуру тестирования. Если функция должна получать более двух аргументов, скорее всего, эти аргументы образуют концепцию, заслуживающую собственного имени.
Это непопулярное мнение, но в большинстве случаев комментарии – зло. Код должен быть самодокументированным. Комментарий – всегда признак неудачи: мы не смогли написать код так, что он понятен без комментариев. Проверьте, можно ли выразить свое намерение в самом коде.
В чём проблема? Программисты умеют сопровождать код, но не комментарии. В растущем коде комментарии быстро устаревают, частично или полностью переставая соответствовать ситуации. Только код правдиво сообщает своим содержанием, что он в действительности делает. Лучше потратить время на исправление запутанного кода, чем добавлять к плохому коду комментарии.
Однако есть несколько видов комментариев, которые выглядят достаточно оправданными.
TODO-комментарии. Бывает так: нужно было успеть к дедлайну, пришлось писать код быстро, поэтому в нем остались дыры. То есть всё работает, но реализация ущербная. Укажите все недоработки и создайте под них задачи. Каждый комментарий указывает на недоработку или потенциальную уязвимость.
Юридические комментарии. Корпоративные стандарты могут принуждать вставлять комментарии по юридическим соображениям. Ограничьтесь в таком комментарии описанием лицензии и ссылкой на внешний документ.
Предупреждения о последствиях. Иногда бывает полезно предупредить других программистов о нежелательных последствиях:
Комментарий также может подчеркивать важность обстоятельства, которое на первый взгляд кажется несущественным.
Бывают такие типы комментариев, которые лучше никогда не делать.
Закомментированный программный код. «Когда-нибудь в будущем раскомментирую этот код, приведу всё в порядок. Или вдруг эта идея кому-то поможет». Любой закомментированный код только ухудшает ситуацию. Все изменения хранятся в контроле версий – удаляйте такой код на корню. Это просто мусор: «потом» равносильно «никогда». Если что-то действительно нужно сделать, создайте краткий TODO-комментарий и задачу.
Мертвые функции – идентичные по смыслу предыдущему пункту функции и методы, которые не вызываются в программе. Пользуйтесь системой контроля версий и без зазрений совести удаляйте любой код, который не используется во время выполнения программы.
Избыточные комментарии. Задайте себе вопрос: стал ли код понятнее после прочтения комментария? Часто комментарии просто загромождают код и скрывают его смысл, излагая очевидные вещи. Иногда в комментарии включаются описания не относящихся к делу подробностей. Но профессионал бережет не только свое, но и чужое время, и не отвлекает читающего без повода.
Журнальные комментарии и ссылки на авторов. Некоторые программисты добавляют комментарий в начало файла при редактировании. Или указывают, кто и когда внес исправления. Когда-то это было оправдано, но теперь у нас есть системы контроля версий – это гораздо лучший способ обозначить границы зоны ответственности каждого.
Позиционные маркеры. Иногда любят отмечать определенные группы и позиции в исходных файлах:
Качественно организованный код способен внятно рассказать историю без балластных заголовков.
Минималистичность. Чем меньше кода, тем лучше. Имя файла должно быть простым, но содержательным. Маленькие файлы обычно более понятны, чем большие. Но размер файла, конечно, не должен быть самоцелью.
Код должен быть максимально линейным. Чем больше вложенность кода, тем сложнее его читать. Следите за тем, как двигаются ваши глаза. В хорошем коде вы двигаетесь строка за строкой, лишь изредка возвращаясь к предыдущим строчкам. Вложенность более трех уровней указывает на то, что с кодом нужно поработать: переписать условия проверок и циклов (использовать return и функциональное программирование), разбить код на меньшие методы.
Отдельные «мысли» следует отделять друг от друга пустыми строками. Каждая пустая строка – зрительная подсказка: описание одной концепции закончилось, далее следует новая. При просмотре кода взгляд концентрируется на первых строчках – в них больше всего информации, как в началах абзацев этого текста.
Тесно связанные концепции, должны располагаться вблизи друг друга. Не заставляйте читателя прыгать между файлами или постоянно скроллить файл. По той же причине переменные нужно объявлять как можно ближе к месту использования. Однако переменные экземпляров лучше объявлять в одном месте, обычно в начале класса, так как в хорошо спроектированном классе переменные используются большинством методов класса.
Пробелы для группировки взаимосвязанных элементов. Пробелы улучшают читаемость кода, если они стоят вокруг операторов присваивания, после запятых при перечислении переменных. В формулах пробелы используются для подчеркивания приоритета: не ставятся между множителями, но отбивают знаки сложения и вычитания.
Отступы. Размер отступов должен соответствовать позиции кода в иерархии. Это общая практика, которая позволяет быстро пропускать области видимости, не относящиеся к текущей ситуации. Не поддавайтесь искушению нарушить правила расстановки отступов для коротких команд.
В системе должны выполняться все тесты. Тесты – главный способ, с помощью которого можно понять, что система контролируема. А только контролируемую систему можно проверить.
Три закона тестирования по методологии TDD. Тестовый код не менее важен, чем код продукта. Соблюдение следующих трех правил позволяет организовать работу так, чтобы тесты охватывали все аспекты кода продукта:
- Не пишете код продукта, пока не напишете отказной модульный тест.
- Не пишите модульный тест в объеме большем, чем необходимо для отказа.
- Не пишите код продукта в объеме большем, чем необходимо для прохождения текущего отказного теста.
F.I.R.S.T. Качественные тесты должны обладать пятью характеристиками, первые буквы которых образуют указанный акроним:
- Fast. Тесты должны выполняться быстро.
- Independent. Тесты не должны зависеть друг от друга и выполняться в любом порядке.
- Repeatable. Тесты должны давать воспроизводимые в любой среде результаты.
- Self-validating. Результат выполнения теста – логический признак: тест пройден или нет. Иначе результаты приобретают субъективный характер.
- Timely. Тест должен создаваться своевременно. Тесты нужно писать непосредственно перед написанием кода.
Повышение уровня абстракции и устранение дубликатов. Все программы состоят из очень похожих элементов, а все задачи программирования сводятся к работе с ограниченным набором действий. Многие из этих действий могут быть описаны в одних и тех же терминах, например, извлечение элемента из коллекции. В подобных ситуациях правильно инкапсулировать реализацию в более абстрактном классе. Повышение уровня абстракции позволяет избежать дублирования и многократно применения одного и того же кода, лучше понять, что действительно происходит в программе, уйдя от частностей.
Если что-то в программе делается снова и снова, значит, какая-то важная концепция не нашла своего отражения в коде. Нужно попытаться понять, что это такое, и выразить идею в виде кода. Избегайте дубликатов, это всегда лишняя работа, лишний риск, лишняя сложность.
Несколько языков в одном исходном файле. Современные среды программирования позволяют объединять в одном файле код, написанный на разных языках. Результат получается запутанным, неаккуратным и ненадежным. Чтобы четко разграничить ответственность, в файле должен преобладать один язык. Сведите к минимуму количество и объем кода на дополнительных языках.
Не нужно бездумно следовать догмам. Не переусердствуйте с сокращением кода функций и классов. Всегда руководствуйтесь здравым смыслом.
Чистый код выглядит так, как если его автор над ним тщательно потрудился. Вы не можете найти очевидных возможностей для его улучшения. Попытавшись его улучшить, вы вновь вернетесь к тому же коду.
Чтобы писать чистый код, который бы никого не удивлял, необходимо раз за разом сознательно применять описанные приемы. При чтении чистого кода вы улыбаетесь, как при виде искусно сделанной музыкальной шкатулки. Код можно назвать красивым, если у вас создается впечатление, что язык был создан специально для этой задачи.
Расскажите нам о правилах, которые вы применяете для написания своего программного кода. Какие open source программы, на ваш взгляд, имеют лучшее качество кода?
Исхо́дный код (также исхо́дный текст) — текст компьютерной программы на каком-либо языке программирования. В обобщённом смысле — любые входные данные для транслятора.
Исходный код либо транслируется в исполняемый код при помощи компилятора, либо исполняется непосредственно по тексту при помощи интерпретатора.
Содержание
Назначение
Исходный код либо используется для получения объектного кода, либо выполняется интерпретатором. Изменения никогда не выполняются над объектным кодом, только над исходным, с последующим повторным преобразованием в объектный.
Другое важное назначение исходного кода — в качестве описания программы. По тексту программы можно восстановить логику её поведения. Для облегчения понимания исходного кода используются комментарии. Существуют также инструментальные средства, позволяющие автоматически получать документацию по исходному коду — т. н. генераторы документации.
Кроме того, исходный код имеет много других применений. Он может использоваться как инструмент обучения; начинающим программистам бывает полезно исследовать существующий исходный код для изучения техники и методологии программирования. Он также используется как инструмент общения между опытными программистами, благодаря своей (идеально) лаконичной и недвусмысленной природе. Совместное использование кода разработчиками часто упоминается как фактор, способствующий улучшению опыта программистов.
Программисты часто переносят исходный код из одного проекта в другой, что носит название повторного использования кода (Software reusability).
Исходный код — важнейший компонент для процесса портирования программного обеспечения на другие платформы. Без исходного кода какой-либо части ПО, портирование либо слишком сложно, либо вообще невозможно.
Организация
Исходный код некоторой части ПО (модуля, компонента) может состоять из одного или нескольких файлов. Код программы не обязательно пишется только на одном языке программирования. Например, часто программы, написанные на языке Си, с целью оптимизации, содержат вставки кода на языке ассемблера. Также возможны ситуации, когда некоторые компоненты или части программы пишутся на различных языках, с последующей сборкой в единый исполняемый модуль при помощи технологии известной как компоновка библиотек (library linking).
Сложное программное обеспечение при сборке требует использования десятков, или даже сотен файлов с исходным кодом. В таких случаях для упрощения сборки обычно используются файлы проектов, содержащие описание зависимостей между файлами с исходным кодом, и описывающие процесс сборки. Эти файлы так же могут содержать и другие параметры компилятора и среды проектирования. Для разных сред проектирования могут применяться разные файлы проекта, причем в некоторых средах эти файлы могут быть в текстовом формате, пригодном для непосредственного редактирования программистом с помощью универсальных текстовых редакторов, в других средах поддерживаются специальные форматы, а создание и изменения файлов производится с помощью специальных инструментальных программ. Файлы проектов обычно включают в понятие «исходный код». В подавляющем большинстве современных языковых сред обязательно используются файлы проектов вне зависимости от сложности прочего исходного кода, входящего в данный проект. Часто под исходным кодом подразумевают и файлы ресурсов, содержащие различные данные, например, графические изображения, нужные для сборки программы.
Для облегчения работы с исходным кодом, для совместной работы над кодом командой программистов, используются системы управления версиями.
Качество
В отличие от человека, для компьютера нет «хорошо написанного» или «плохо написанного» кода. Но то, как написан код, может сильно влиять на процесс сопровождения ПО. О качестве исходного кода можно судить по следующим параметрам:
- читаемость кода (в том числе наличие или отсутствие комментариев к коду;
- лёгкость в поддержке, тестировании, отладке и устранении ошибок, модификации и портировании;
- низкая сложность;
- низкое использование ресурсов — памяти, процессора, дискового пространства;
- отсутствие замечаний, выводимых компилятором;
- отсутствие «мусора» — неиспользуемых переменных, недостижимых блоков кода, ненужных устаревших комментариев и т. д.
Неисполняемый исходный код
Копилефтные лицензии для свободного ПО требуют распространения исходного кода. Эти лицензии часто используются также для работ, не являющихся программами — например, документации, изображений, файлов данных для компьютерных игр.
В таких случаях исходным кодом считается форма данной работы, предпочтительная для её редактирования. В лицензиях, предназначенных не только для ПО, она также может называться версией в «прозрачном формате». Это может быть, например:
Читайте также: