Как выглядит компьютерный код программы
Исхо́дный код (также исхо́дный текст) — текст компьютерной программы на каком-либо языке программирования или языке разметки, который может быть прочтён человеком. В обобщённом смысле — любые входные данные для транслятора. Исходный код транслируется в исполняемый код целиком до запуска программы при помощи компилятора или может исполняться сразу при помощи интерпретатора.
Содержание
Исходный код либо используется для получения объектного кода, либо выполняется интерпретатором. Изменения выполняются только над исходным, с последующим повторным преобразованием в объектный.
Другое важное назначение исходного кода — в качестве описания программы. По тексту программы можно восстановить логику её поведения. Для облегчения понимания исходного кода используются комментарии. Существуют также инструментальные средства, позволяющие автоматически получать документацию по исходному коду — т. н. генераторы документации.
Кроме того, исходный код имеет много других применений. Он может использоваться как инструмент обучения; начинающим программистам бывает полезно исследовать существующий исходный код для изучения техники и методологии программирования. Он также используется как инструмент общения между опытными программистами благодаря своей лаконичной и недвусмысленной природе. Совместное использование кода разработчиками часто упоминается как фактор, способствующий улучшению опыта программистов.
Программисты часто переносят исходный код (в виде модулей, в имеющемся виде или с адаптацией) из одного проекта в другой, что носит название повторного использования кода.
Исходный код — важнейший компонент для процесса портирования программного обеспечения на другие платформы. Без исходного кода какой-либо части ПО портирование либо слишком сложно, либо вообще невозможно.
Исходный код некоторой части ПО (модуля, компонента) может состоять из одного или нескольких файлов. Код программы не обязательно пишется только на одном языке программирования. Например, часто программы, написанные на языке Си, из соображений оптимизации содержат вставки кода на языке ассемблера. Также возможны ситуации, когда некоторые компоненты или части программы пишутся на различных языках, с последующей сборкой в единый исполняемый модуль при помощи технологии, известной как компоновка библиотек (library linking).
Сложное программное обеспечение при сборке требует использования десятков или даже сотен файлов с исходным кодом. В таких случаях для упрощения сборки обычно используются файлы проектов, содержащие описание зависимостей между файлами с исходным кодом и описывающие процесс сборки. Эти файлы также могут содержать параметры для компилятора и среды проектирования. Для разных сред проектирования могут применяться разные файлы проекта, причём в некоторых средах эти файлы могут быть в текстовом формате, пригодном для непосредственного редактирования программистом с помощью универсальных текстовых редакторов, в других средах поддерживаются специальные форматы, а создание и изменения файлов производится с помощью специальных инструментальных программ. Файлы проектов обычно включают в понятие «исходный код». Часто под исходным кодом подразумевают и файлы ресурсов, содержащие различные данные, например графические изображения, нужные для сборки программы.
Для облегчения работы с исходным кодом и для совместной работы над кодом командой программистов используются системы управления версиями.
В отличие от человека, для компьютера нет «хорошо написанного» или «плохо написанного» кода. Но то, как написан код, может сильно влиять на процесс сопровождения ПО. О качестве исходного кода можно судить по следующим параметрам:
- читаемость кода (в том числе наличие комментариев к коду);
- лёгкость в поддержке, тестировании, отладке и устранении ошибок, модификации и портировании;
- экономное использование ресурсов: памяти, процессора, дискового пространства;
- отсутствие замечаний, выводимых компилятором;
- отсутствие «мусора» — неиспользуемых переменных, недостижимых блоков кода, ненужных устаревших комментариев и т. д.;
- адекватная обработка ошибок;
- возможность интернационализации интерфейса.
Копилефтные лицензии для свободного ПО требуют распространения исходного кода. Эти лицензии часто используются также для работ, не являющихся программами — например, документации, изображений, файлов данных для компьютерных игр.
В таких случаях исходным кодом считается форма данной работы, предпочтительная для её редактирования. В лицензиях, предназначенных не только для ПО, она также может называться версией в «прозрачном формате». Это может быть, например:
- для файла, сжатого с потерей данных — версия без потерь;
- для рендеравекторного изображения или трёхмерной модели — соответственно, векторная версия и модель;
- для изображения текста — такой же текст в текстовом формате;
- для музыки — файл во внутреннем формате музыкального редактора;
- и наконец, сам файл, если он удовлетворяет указанным условиям, либо если более удобной версии просто не существовало.
Любая программа или онлайн-сервисы, например, Word, Microsoft Windows, WhatsApp или же браузер, которые ежедневно запускают сотни миллионов человек, так или иначе, состоят из особых инструкций. Или специального программного кода, который понятен машине, говорит, что ей делать или, наоборот, не делать. Или как правильно реагировать на действия пользователя. Что такое программный код, будет разобрано в этой статье.
Описание
Программный код программы — это текст, выполненный на особом языке, понятном машине. Он может выполняться непосредственно по тексту с помощью интерпретатора или транслироваться в особый вид с помощью компилятора.
Исходный код программы может состоять из нескольких файлов. При этом все они должны быть одинакового формата. Текст программы, содержащейся в них, должен быть написан на одном и том же языке. Правда, могут встречаться и исключения. Например, в веб-разработке в файле страницы могут содержаться несколько различных языков программирования и стандартов. В зависимости от сложности проекта, могут присутствовать такие языки и технологии, как PHP, HTML, JavaScript, Java и другие.
Сложные программные комплексы при сборке могут потребовать большого количества файлов, которое может исчисляться целыми сотнями. Для совместной работы над такими большими проектами программисты очень часто используют системы контроля версий. Они позволяют одновременно работать с несколькими экземплярами исходного кода, который на определённом этапе разработки можно соединить в один общий.
Качество кода
Компьютер не способен понять, как написан код для него, плохо или хорошо. Если он будет работоспособен и не содержит ошибок, то машина запустит его в любом случае. Плохой код может усложнить задачи сопровождения программного обеспечения. Особенно актуально это для больших проектов. Обычно качественный код характеризуется несколькими параметрами:
- Читаемость кода. Одного взгляда на него должно хватать, чтобы обобщенно понять, что реализуется участком кода.
- Присутствие понятных и ёмких комментариев. Данный параметр очень сильно влияет на читаемость, легкость в отладке, тестирование поддержки и устранение ошибок программного кода.
- Низкая сложность.
- Оптимизация кода. Организовать его стоит таким образом, чтобы программа использовала как можно меньше системных ресурсов, таких как память, время процессора и пространство жёсткого диска.
- Отсутствие мусора. То есть не используемых переменных или блоков кода, в которой никогда не заходит управление программой.
Вредоносный программный код
Помимо полезных программ, существуют такие, которые могут нанести вред системе или даже оборудованию. Как правило, пишется такой код людьми, которые заинтересованы в какой-либо выгоде от происходящего процесса. Например, программы, которые могут похищать личные данные с компьютеров пользователей. Ими могут быть номера платёжных карт, паспортные данные, или какая-либо другая конфиденциальная информация. Другие могут просто оказывать влияние на работу системы, тем самым вызывая сбои и мешая полноценной функциональности.
Рекомендации по написанию хорошего кода
Джефф Вогел — программист с большим опытом — поделился несколькими советами для того, чтобы научить начинающих разработчиков правилам хорошего кода.
В частности, он предлагает всегда комментировать свой программный код. Что такое комментарий? Это понятное и краткое описание того, что происходит в данной строке кода или функции. Дело в том, что разработка определённой программы может затянуться на месяц или вообще приостановиться на некоторое время. Вернувшись к работе над проектом через пару месяцев, даже опытному программисту будет сложно разобраться в своей же программе. Но подробные комментарии смогут восстановить цепочку событий и поведение кода.
Далее он рекомендует использовать в программе глобальные переменные как можно чаще. Это объясняется тем, что при изменении программного кода, придётся корректировать значение переменной всего лишь в одном месте. При этом все использующие значение функции или процедуры сразу об этом узнают и будут производить операции уже с новыми данными.
Имена переменных и выявление ошибок
Правильное название переменных также поможет значительно сократить время на изучение исходного кода программы, даже если код написан собственными руками. То есть хорошим кодом считается такой текст, где переменные и функции имеют имена, по которым можно понять, что именно они делают или хранят. При этом нужно стараться не использовать длинных имён переменных.
Очень важно уделять большое внимание своевременному устранению ошибок. Что такое программный код, который исполняется идеально? Это код, в котором нет ошибок. То есть любое ветвление цикла или изменение переменной, или вовсе какие-либо непредвиденные действия пользователя, всегда приведут к ожидаемому результату. Это достигается за счёт тестирования готового программного продукта по несколько раз.
Выявление ошибок программного кода, а точнее, их предугадывание возможно на этапе проектирования программы. Присутствие в коде различных проверок условий и возможных исключений, поможет вести управление программой по определённому курсу.
Оптимизация имеет колоссальное значение для написания работоспособной программы, которая будет экономно использовать ресурсы компьютера и при этом не допускать ошибок выполнения программного кода. Что такое оптимизированная программа? Это продукт, который способен выполнять весь заявленный функционал, ведя себя при этом "тихо" и экономно.
Практически всегда оптимизации для стабильной работы программы можно добиться только в результате проведения нескольких тестов на разных платформах и в различных условиях. Если программа начинает вести себя непредсказуемо, нужно определить, что стало причиной и по возможности устранить или перехватить процесс.
Заключение
Что такое программный код? Говоря простым языком, это набор инструкций и понятий для компьютера. Он содержит текст, который компилятор или интерпретатор могут превратить в понятный машине язык. То есть, по сути, программный код — это посредник между человеком и компьютером, который упрощает их взаимоотношения.
Исходный код — это текст компьютерной программы на языке программирования или языке разметки, который состоит из цифр и букв английского языка для понимания человеком. Исходный код компьютерной программы транслируется в исполняемы код, понятный для компьютера, и запускает работу программы с помощью компилятора или выполняет код через интерпретатор. С исходным кодом работают программисты, прописывая всю логику работы программы, добавляя комментарии в наиболее сложные участки кода для понимания их работы другими программистами, генерируя автоматическими инструментами документацию исходного кода.
Комментарии и документация, да и сам по себе исходный код программы, предназначен не только для понимания принципов и логики работы программы и отдельных ее частей, но и для обучения начинающих программистов, изучения применяемых техни и методологии разработанной программы. Совместное использование программного кода позволяет улучшать общий опыт работы программистов.
Так как очень часто одни и те же участки программного кода используются в нескольких местах программы, либо задействованы в нескольких других программах, такие участки кода принято выделять в модули и компоненты, которые можно в любой момент быстро подключить и использовать в нужной программе. Такое действие назвается — повторным использованием программного кода. Это очень облегчает разработку программ и делает ее заметно быстрей, без необходимости повторно писать одни и те же участки программного кода.
В случае применения таких модулей и компонентов, да и вообще, исходного кода самого по себе, важным моментом является переносимость на другие программные платформы, их правильная работа на этих платформах.
Переносимые модули и компоненты с исходным кодом могут состоять из одного и более файлов (десятки, тысячи файлов с кодом), а также написаны на разных языках программирования. Например, часть программы на языке программирования Си, может содержать части кода на языке ассемблера.
Для удобства и облегчения работы с исходным кодом существует множество инструментов, позволяющий автоматизировать написание кода, обеспечивать командную работу над кодом, создавать и контролировать различные версии программ.
Для компьютера, нет разницы и понимания «хорошего кода» или «плохого кода». Программисту же, для понимания что происходит в программе, написанной другим программистом, поддержки и написания новых частей программы, качество исходного кода является очень важной вещью. Ведь если код будет труден для понимания, его невозможно прочитать, а если возможно, но на это уходит много времени, то разработка и поддержка программы существенно усложнит жизнь программиста. Поэтому качество кода должно соответствовать следующим требованиям:
В предыдущей части мы затронули азы программирования, где рассказали о машинном языке, преобразователях, языках программирования и работе с 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:
Набор практик хорошего кода, не зависящих от языка программирования. Примените их, и ваш код будет не только работать, но и читаться.
Программисты в первую очередь работают с языком. Поэтому написание программ похоже на любой другой вид письменной работы. Сначала вы излагаете свои мысли как есть, а затем «причесываете» до тех пор, пока текст не будет легко читаться. Качество кода – результат проявления небезразличного отношения к делу и показатель профессионализма.
Чтение кода происходит чаще, чем написание. Есть большая разница между обучением программированию и реальной работой в компании. Вначале мы и пишем, и читаем собственные программы. Но чем дальше мы продвигаемся, тем чаще нам приходится не писать, а читать код. Чем легче код читается, тем проще с ним работать другим людям.
Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете
Чем проще читать код, тем проще его сопровождать. Понятный, читаемый код легче тестировать, в нем легче отлавливать ошибки – они не скрываются в его запутанной структуре. Плохо оформленный код неприятно изучать, читать, тестировать, сложно дополнять. Рано или поздно плохой код становится проще переписать.
Эстетическое восприятие кода влияет на удобство работы. Казалось бы, гораздо важнее производительность, возможность модификации, расширения… Но все эти показатели улучшаются, если код соответствует нашему чувству прекрасного. Глядя на качественно написанный код, можно быстро понять алгоритм и то, как работает программа для разных входных данных. Чистый код читается, как хорошо написанная проза: слова превращаются в зрительные образы.
Стиль кода определяет его будущее. Стиль и дисциплина продолжают жить в коде, даже если в нем не осталось ни одной исходной строки.
Все дороги программиста ведут к документации. В каждом языке существует свой стандарт оформления кода. Для 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 программы, на ваш взгляд, имеют лучшее качество кода?
Больше полезной информации вы найдете на наших телеграм-каналах «Библиотека программиста» и «Книги для программистов».
В предыдущей части мы познакомились с разновидностями ошибок и отладкой. Двигаемся дальше и переходим от строго теоретических основ к более глубокому изучению и пониманию программирования.
Строка кода, выражения и операторы
Единицей любого исходного кода является LOC (строка кода). Простейшая программа – это и есть строка. LOC может быть ключевым словом, символом или инструкцией. Это строка до тех пор, пока она расположена на отдельной линии кода.
Рассмотрим простую строку:
0.5 * base * height – это выражение. Выражение представляет собой комбинацию операторов и операндов. В приведенном здесь примере операнды – это 0.5, base и height. Напомним, что 0.5 – это число с плавающей запятой, а base и height – переменные. Оператором является * (умножение).
Но выражения не могут быть значимыми, оставаясь просто строками. Когда мы присваиваем значение выражения другой переменной, мы получаем то, что называется инструкцией (statement) – самой малой автономной частью ЯП. Если мы добавим к выражению ключевое слово, это все еще будет инструкцией. Например: return 0.5 * base * height
В нашей статье statement будет представлен как символ S, а n-ая инструкция – как Sn в последовательности (или множестве) инструкций.
Чтобы быстро понять программный код и кодинг в целом, нужно разобраться с порядком выполнения программы. Изучив основные операции, вы с легкостью сможете находить их во многих языках программирования, которые освоите.
Обратите внимание, что примеры, приведенные в этой статье, являются базовыми. Вам следует опираться на изучаемый язык программирования, чтобы получить глубокое знание ключевых слов, которые он предоставляет.
Также основные операции, перечисленные в статье, отличаются от шаблонов проектирования (паттернов) в программировании. Сначала поймите базис, опираясь на который, в дальнейшем вы сможете без труда освоить шаблоны проектирования.
Вот основные операции в программировании:
- Последовательные
- Условные/Ветвление
- Итерационные/Повторяющиеся/Зацикленные
Разберем их более подробно.
Последовательные операции
Это основные операции, в рамках которых один оператор выполняется после другого:
В некоторых языках программирования, таких как JavaScript, S3 можно выполнить еще до S1. Это происходит, если S1 блокируется некоторыми задачами, для выполнения которых может потребоваться больше времени, например, для базы данных или асинхронных задач. Есть способы обойти подобные случаи. Это будет несложно после того, как вы выберете подходящий для изучения язык программирования.
Условные операции/Ветвление
Инструкция, которая выполняется, определяется условиями. В этом поможет оператор условного выбора ветви if, без которого не обходится практически ни один программный код.
В приведенном выше примере выполняется либо S1, либо ничего не происходит. S1 выполняется, только если заданное условие истинно.
Вот еще один пример:
Его можно прочитать как запуск либо S1-S2, либо S3-S4 в зависимости от условия. Если условие истинно, выполняются S1 и S2. В противном случае будут выполняться S3 и S4. В действительности это представляет собой последовательный вывод:
Существуют также многоуровневые условия:
Здесь, если первое условие (condition1) истинно, запускается S1. В противном случае проверяется второе условие (condition2), и если оно истинно, происходит выполнение S2. И таких вариантов может быть много.
Но в многоуровневых условиях лучше применять оператор switch, поддерживаемый большинством языков программирования. Разберем switch на примере:
Первое и второе условия сравниваются с применением инструментов switch. Если какое-либо из них истинно, то выполняется оператор в соответствующем блоке case.
Существуют и другие варианты условных операций. Некоторые из них относятся к конкретному языку программирования, который вы решили изучать. Например, условный оператор (: ?) и прочие ключевые слова, которые облегчают ветвление, такие как cycle (цикл) и break (прерывание).
Итерационные/Повторяющиеся/Зацикленные операции
Сложно представить качественный программный код без единого цикла. Итерационная/повторяющаяся операция обеспечивает выполнение до тех пор, пока оно соответствует заданному условию. Выполнение завершается только тогда, когда условие перестает быть истинным (становится false).
В приведенном выше примере S1 и S2 будут выполняться один раз, несколько раз или вообще не выполнятся. Если заданное условие в цикле while истинно, тогда происходит обработка и запуск S1, S2. После этого условие while снова проверяется, и S1 с S2 будут выполняться до тех пор, пока условие истинно.
В тот момент, когда условие станет ложным, выполнение S1 и S2 прекратится.
Результат из примера выше, если условие истинно трижды:
Что это за операция? Правильный ответ – последовательная. Как видите, другие типы операций не исключают наличие последовательности.
Вот еще один шаблон итерации:
В этом примере S1 и S2 будут выполняться один или более раз. Это происходит потому, что выполнение объявлено еще до проверки состояния, а следовательно, один раз выполнение пройдет наверняка.
Во многих языках программирования для реализации повторяющихся операций предусмотрены ключевые слова, такие как do и while. Другим ключевым словом является for.
Небольшой пример с применением оператора цикла for:
Во многих языках foreach используется для обработки каждого элемента сложного объекта, такого как массив или структура.
Двигаемся дальше
Мы рассмотрели основные операции, которые включает в себя любой программный код. Помимо перечисленных, существует и множество других. Также есть:
-
– подпрограммы, всегда возвращающие результат. – фрагменты программы, которые можно вызывать из любого места кода.
В разных языках программирования эти составляющие реализовываются по-разному.
На данном этапе вы уже изучили основные концепции программирования. Для дальнейшего совершенствования существует много ресурсов, которые помогут вам учиться. Поначалу многие вещи и термины от ведущих программистов будут казаться непонятными, но со временем вы изучите принципы работы отдельных элементов кода, начнете практиковаться и обязательно достигните необходимого уровня.
На нашем сайте есть немало видеуроков, которые помогут во всем разобраться и построить карьеру в сфере разработки. Вот лишь некоторые из них:
Викторина
Определите типы операций, которые использованы в следующем фрагменте кода Python:
Исторически сложилось что разработка программного обеспечения проводится посредством набора обычного текста. Вот уже несколько десятилетий основной подход к программированию состоит в последовательном наборе символов, которые должны формировать структуры более высокого уровня чем эти символы. Программисту приходится не просто раз за разом набирать одни и те же сочетания клавиш, но и следить за правильностью форматирования кода, иначе компьютер просто откажется понимать, что в коде написано. Один забытый символ ";" может выдать совершенно невнятные ошибки компиляции/интерпретации. Более того - использование текстового представления программы не просто ставит дополнительные требования к программированию, но и сильно ограничивает возможности программиста для эффективного написания и использования кода. Также текстовое представление информации сильно усложняет анализ этой информации программным способом. Давайте разберемся с альтернативным подходом к написанию программ.
Знакомьтесь - это MetaIDE. Один из представителей визуального/структурного подхода к обработке и хранению информации. Любой оператор (наподобие for, if, while) это не набор простых текстовых символов, а конкретный цельный элемент в памяти компьютера. Любой код программы - это набор из фиксированных операторов, которые составляют структурное представление программы. При использовании большинства обычных языков программирования, компилятор парсит исходный текст программы и строит AST - Abstract syntax tree (Абстрактное синтаксическое дерево). В MetaIDE вся программа уже являет собой AST, что сильно упрощает написание кода и последующее его использование.
Создание программного кода
Написание программного кода напоминает обычное текстовое программирование. Разве что вместо полнотекстового ввода операторов, в MetaIDE можно ограничиться всего парой клавиш: wh для while, fo для for и т.п. Также все операторы уже имеют необходимую разметку, что ускоряет набор кода. Среди программистов часто говорят, что скорость набора якобы не важна, но на практике, пока держишь в голове все детали алгоритма, очень желательно поскорее внести его в компьютер. Необходимость форматирования текста при этом только отвлекает. Структурное программирование позволяет более быстрее набирать исходные код. Особенно учитывая, что у IDE гораздо больше возможностей помочь программисту. Также стоит заметить, что для создания структурной программы, клавиатура не обязательна. Все основные операторы можно вводить с помощью меню. Простой текстовый ввод в основном необходим для задания имен переменным, функциям и т.п. Такой подход может хорошо зарекомендовать себя в случаях, когда нет полноценного доступа к клавиатуре - например на планшете (телефоне) или устройстве VR. Да и вообще - кто бы не хотел писать программу попивая чай одной рукой, а второй - спокойно и эффективно набирать код.
Отображение кода
Scratch, UML, Unreal Engine
Как и в визуальном программировании, структурный код может быть представлен в любом формате. Например, как пазлы (Scratch, Blockly), как блоксхемы (UML, Дракон), как чертежи (blueprints - Unreal, Unity). Конкретно в MetaIDE используется представление кода максимально близкое к обычному текстовому представлению. Это позволяет разместить максимум информации на экране к чему привыкли опытные программисты.
Свобода в представлении информации позволяет делать локализованные версии кода, что может быть удобно в учебных целях. Не смотря на разное представление, исходный код при этом остается без изменений, и на других платформах может выглядеть по-другому, адаптируясь под конкретную платформу.
Также такой подход к отображению кода упрощает чтение и разработку программы. Например, большинство программ требуют локализации. Чаще всего для локализации используют перечисления (enum) которые имеют краткое описание текста. Но для программиста такой подход не совсем удобен - перечисление может не полностью отображать суть текста что приводит к ошибкам в использовании не тех строк, а добавление нового текстового значения требует перекомпиляции всей программы. В структурной программе можно создать специальное значение для локализованной строки - это позволит отображать текст строки прямо в коде (с возможностью выбора локали), упростит компиляцию (хранится обычное цифровое представление вместо перечисления), сделает более удобную локализацию (новые строки для локали можно добавлять прямо "из кода" не прибегая к дополнительным инструментам).
Как это все работает
Таким образом MetaIDE реализует популярный архитектурный шаблон MVC (Model-View-Controller, Модель-Представление-Контроллер) и обеспечивает максимальную гибкость при работе с данными. На каждую ноду можно создать множество разных виджетов и это активно используется в представлении кода. Например, декларация локальной переменной (или функции, класса, типа) содержит в себе имя, а все места где эта переменная используется - на самом деле указатели на декларацию и используют виджет для отображения имени по этому указателю. Так что изменив имя переменной, изменится также выводимый текст всюду, где встречается эта переменная.
Как с этим работать
Здесь все еще проще - активировав ноду (вернее виджет представляющий ноду), слева в меню появятся все возможные действия, которые можно выполнить с этой нодой. За каждым пунктом меню стоит скрипт изменяющий ноду. Также в меню можно ознакомиться с комбинациями клавиш необходимыми для выполнения конкретного пункта меню.
Единое пространство
Поскольку почти все в MetaIDE состоит из нод, значит любой скрипт может получить доступ к любой части данных IDE, и прочитать или модифицировать их на свое усмотрение. Даже модифицировать свой собственный исходный код. Таким образом, написать дополнение к структурной IDE в разы легче чем для обычной IDE - фактически достаточно знать какие ноды нужно изменить и как это сделать (никаких SDK или ограниченных API, как в случае с текстовым исходным кодом).
Генерация кода, метапрограммирование и DSL
Часто бывают ситуации, когда в исходный код нужно добавить новую сущность что тянет за собой создание нового класса для этой сущности, пары функций для обработки сущности, значение в enum, текстовое описание, добавление указателей в массивы и т.п. И все это раскидано по разным файлам и даже проектам. Один раз прописывать весь код не составляет особых проблем, но вот если таких сущностей десятки, а то и сотни, ручная прописка всех необходимых мест начинает сильно усложнять разработку. К тому же спустя некоторое время все нюансы создания кода забываются, и добавление чего-либо нового в программу занимает уйму времени. Обычный подход к программированию мало приспособленный к такой проблеме. В языках программирования могут быть макросы и темплейты, которые лишь частично помогают в организации однотипного кода. MetaIDE предлагает другой подход к решению - создание DSL (или даже обычного UI) который в краткой форме описывает необходимые данные, и пары скриптов которые будут генерировать финальный код и прописывать его во все нужные места. Создание такого генератора в структурном коде на порядки проще чем создание его менее удобного аналога для обычных текстовых исходников.
Больше чем IDE
Карта памяти
На самом деле MetaIDE это не только среда для разработки программ, но и среда для работы этих же программ. Так в MetaIDE разработаны дополнительные инструменты для организации рабочего процесса (пока в очень базовой форме) - карты памяти (mind map), текстовый структурный редактор (outliner), скрипты и виджеты для подбора цветов (в пространствах HSB, LCH, HSLuv, HPLuv). Кроме того, разрабатывая программы для MetaIDE, можно сразу использовать набор готовых виджетов, стандартные скрипты и разметки для более простой работы с нодами, готовую систему истории изменений (undo/redo) и сохранения данных на диск. В будущем планируется добавить систему контроля версий для нод (такой себе git), возможность создавать любые виджеты с помощью скриптов, а также компиляция готовых программ в исполняемые файлы под разные ОС.
Выбор цветов для меню
Помощь с легаси
Важной составляющей структурного представления кода, является простота чтения и модификации кода с помощью скриптов. Фактически весь код – это набор объектов, которыми легко манипулировать, в том числе транслировать старый код под новые требования, что сильно облегчает работу с устаревшими данными. Вместо ручного переписывания старых данных под новый формат, можно написать скрипт, который выполнит большую часть работы автоматически.
Язык Delight
Список операторов
Для написания скриптов в MetaIDE используется структурный язык программирования Delight. По синтаксису он ближе всего к Паскалю и С++, однако имеет множество нововведений, в том числе компонентно-ориентированное программирование (вместо ООП), но это уже тема другой статьи.
История разработки
Описание нод, виджетов и меню
Лучше всего использование всех возможностей структурного подхода к организации информации просматривается на истории создания самой MetaIDE. Изначально весь код писался в Lazarus, соответственно существовал только код паскаля. На паскале был написан язык описания шаблонов нод, с помощью которого было легко создавать новые типы нод. Поскольку сам язык описания нод был вполне самодостаточен, то уже мог описать сам себя. Был написан скрипт, который прокидывал все существующие ноды на уже созданные шаблоны нод (созданные уже на нодах, а не на паскале). Фактически новая структура нод начала ссылаться сама на себя, и стала менее зависима от паскаля, что позволило выкинуть большую часть паскалевского кода. Общее количество кода сильно сократилось, при том что старые данные нод успешно конвертировались в новую структуру в автоматическом режиме. На новой структуре нод начал создаваться язык программирования Delight, и здесь проявились недостатки в шаблонном описании нод – на тот момент нода описывалась своим визуальным представлением вперемешку со своими данными, что было крайне неудобно для интеграции с Delight. Было решено сделать описание нод в виде близком к описанию классов (как в обычных ЯП), а визуальное представление ноды вынести в отдельные виджеты. Однако на тот момент уже существовали сотни описаний нод на которых держалась вся IDE и Delight. Задачу можно сравнить с необходимостью разделения кода декларации класса на несколько частей, а таких классов в программе - сотни. Фактически требовалось переписывание всего кода с нуля. К счастью, имея дело с структурированной информацией, всего за два вечера были написаны скрипты, которые конвертировали устаревшее представление данных в новый формат. Ручное переписывание заняло бы пару недель. В последствии, автоматическое переписывании кода с помощью скриптов использовалось регулярно. Так в один момент, данные уже созданных библиотек нод были разделены на две части, проводились тотальные изменения в синтаксисе и архитектуре Delight - чего только стоил перевод всех существующих исходных кодов с ООП и интерфейсами на КОП. Все эти задачи успешно решались написанием скриптов вместо ручного переписывание всего существующего кода. Фактически вся разработка MetaIDE и Delight напоминала эволюционное программирование - когда все старые данные без проблем эволюционировали в новые, более эффективные представления.
Ложка дегтя
Конечно работа со структурными данными довольно сильно отличается от обычной работы с текстом. Если при оперировании с текстовым представлением, достаточно любого текстового редактора со стандартным и знакомым всем функционалом, то работа со структурными данными практически не возможна без использования скриптов и знания как эти скрипты функционируют. С другой стороны, если для текстового программированная нужно досконально знать синтаксис языка программирования, то для структурного программирования можно просто пользоваться подсказками IDE для создания кода.
Ложка дегтя №2
На текущий момент MetaIDE и Delight находятся в стадии разработки и доступны только в качестве предварительного просмотра (даже не как альфа версия). Далеко не все еще доработано и не все вещи сделаны удобно. Масштабы разработки слишком громадны и на проработку всех деталей за раз не хватает времени.
Обширный todo list
Выводы
На данный момент MetaIDE представляет собой совершенно новый подход к написанию программ, открывая для программиста новые горизонты в организации всего рабочего процесса. Сильно упрощается как работа с кодом в целом, так и отдельные аспекты программирования.
Читайте также: