Прикладной или системный?
Евгений Каратаев
В
разработке программы встречаются неясные вопросы относительно того,
как
спланировать тот или иной код, куда его отнести и как
классифицировать. Код
может быть классифицирован по самым различным классификациям - на
код верхнего
и нижнего уровня, на специфичный и библиотечный, и другим.
Правильная
классификация зачастую на первых же шагах разработки (как
проектирования, так и
реализации) может помочь в выявлении ошибок. Если читаешь схему
данных или код,
предназначенный для выполнения определенной задачи, которая
классифицируется
определенным образом и при этом код имеет признаки классификации
не
соответствующей задаче, то у меня срабатывает рефлекс и этому коду
(схеме,
диаграмме) я сразу приписываю проблемный крестик. Независимо от
текущего
положения дел расхождение классификационных признаков задачи и
реализации есть
индикатор по крайней мере потенциальной ошибки или мины, которая
рано или
поздно сработает.
Одним
из предметов споров иногда может выступать деление как
программистов, так и
кода на прикладных и системных. К системным программистам
традиционно относят
разработчиков операционок, драйверов, инструмента, а остальных - к
прикладным.
Здесь я опишу свое видение классификации кода по признаку -
прикладной или
системный.
Сразу
можно помолчать, выслушать кучу вопросов и попыток уточнения вроде
"А
смотря что понимать под прикладным". Вот в таком виде, чтобы было
понятно
без подобных уточнений, и поведем дальше речь.
Одна
из основных аксиом программирования гласит, что программа есть
виртуальная
машина для преобразования или передачи информации, сама по себе
являющаяся
информационной сущностью. Программа по отношению к одному слою
является
переработчиком информации, а по отношению к другому слою
(операционная система)
- перерабатываемая информация. Таким образом, рассматривая основные
способы
построения программ как сущностей в контексте операционной системы,
можно
утверждать, что существует объект, который обрабатывает программу
и
поддерживает ее функционирование.
Связывание
же двух противоположных сущностей - алгоритмов как неизменяемых и
исполняемых
информационных объектов и данных как изменяемых и неисполняемых
объектов
производится через определенные соглашения о вызове. Эти соглашения
называются
декларацией типа и описывают, каким именно образом алгоритм должен
получать
доступ к обрабатываемой памяти. Прекрасной иллюстрацией может
служить
использование в языках высокого уровня различения между знаковым и
беззнаковым
целым. Программист для обоих типов может использовать одинаковые
операции,
например, сложение. Но при этом транслятор, имея сведения о типе
целого
(знаковый или беззнаковый), генерирует различный машинный код.
Дальнейшим
развитием понятия типа является понятие класса в объектно -
ориентированных
языках. Если говорить о С++, то на нем программист может
переопределить в том
числе и встроенные операции языка, например, определить операцию
сложения для
строк. Синтаксически использоваться же будет по-прежнему оператор
сложения, но
транслятор, имея информацию о типе, будет генерировать код,
описанный
программистом в перегруженном операторе.
Несложно
видеть, что реализация типизированного доступа в обоих случаях
опирается на
"используя информацию о типе". Независимо от того, как именно
реализуется поддержка типов - на этапе генерации кода, с
применением таблиц
виртуальных функций или присоединением теговых данных, где-то все
равно должна
существовать соответствующая информация.
Именно эта информация и
определяет
поведение исполнительного механизма доступа. Таким образом,
обрабатываемая
информация описывается как собственно ее содержанием, так и ее
форматом
доступа.
Довольно
общеизвестные сведения, приведенные выше, нужно рассматривать как
освежение
знаний и погружение в контекст вопроса. Теперь о сути темы. Мое
мнение по
вопросу разделения кода на системный или прикладной состоит в
правиле - если
исполнение кода и его течение определяется форматом данных, то это
системный
код, а если код зависит от содержания данных, то это прикладной
код. Правило
очень простое, хотя и, может быть, спорное. Тем не менее мне оно
помогает в
планировании модулей и в проектировании.
Как
различить код, зависящий от значений данных и не зависящий от
значений данных.
Просто надо посмотреть точки ветвлений программы (функции),
условных переходов
и циклов и определить, от чего зависит выполнение условия. Если от
значения
данных, к тому же обрабатываемых, то код должен быть отнесен к
прикладному.
Если только от неких констант, типов, данных описывающих формат
других данных,
то это системный код. Более того - такая оценка может выявить
очевидные
логические ошибки. Например, если в коде написано, что если
параметр
беззнаковый, то делать одно, а если больше 12, то другое. Приведем
несколько
примеров, демонстрирующих различение прикладного и системного
контекстов.
string
func( string str)
{
int len = strlen(
str.c_str());
for( int i = 0; i
str[i] = WinToKoi( str[i]);
return
str;
}
В
этом примере код не зависит от значения символов в строке. Какие бы
они ни
были, программа будет исполняться точно так же. Таким образом, этот
код
является системным.
string func( int sum)
{
if( sum
return "мало";
if( sum
return "нормально";
if( sum
return "много";
return "очень много";
}
В
этом коде выполнение алгоритма явно зависит от значений данных.
Поэтому такой
код я классифицирую как прикладной.
При
разработке программы я бы счел хорошим стилем размещение
приведенных функций в
разных модулях, с тем, чтобы существовали модули, отвечающие за
прикладную
часть и за системную часть. Впрочем, для небольшой программы
размещение таких
функций в одном модуле может быть вполне оправдано.
Кроме
приведенного правила классификации кода на системный и прикладной
следует
обращать внимание на смешанный случай, существующий в явном виде
при
составлении функций, оперирующих визуальным представлением данных.
При
визуализации данных следует учитывать существование национальных
стандартов
представления данных, которые могут различаться так же и
форматом
представления. Например, при визуализации времени по российскому
стандарту
следует указывать час, минуту и секунду, а при визуализации по
английскому
стандарту следует дописывать еще и символы представления
"AM/PM".
Таким образом, код независящий от значения данных, начинает
зависеть от
контекста его работы, который есть данные. Еще более сложный случай
-
формирование визуализации строкового представления с применением
особенностей
языка, например "сумма прописью". К какой категории отнести
такую
функцию? Думаю, что к прикладной.
Приведенное
правило классификации, конечно, не есть догма. Но лично я
стараюсь
придерживаться таких простых правил в работе и они мне помогают
в
проектировании и отыскании ошибок.
Список литературы
Для
подготовки данной работы были использованы материалы с сайта
http://karataev.nm.ru/
Прикладной или системный?
73
0
4 минуты
Темы:
Понравилась работу? Лайкни ее и оставь свой комментарий!
Для автора это очень важно, это стимулирует его на новое творчество!