Ядро архитектуры
Ядро архитектуры (программное ядро) — это определенный принцип построения программного обеспечения и реализации повторного использования. До сих пор обобщенных определений дано не было, но как правило, об архитектуре ядра говорят применительно к операционным системам. Со временем, выделение так называемого ядра стали осуществлять в крупных программных комплексах. Другое возможное использование этого термина применяют когда разрабатываются некие независимые библиотеки программ (SDK), так например, говорят о графических или физических движках.
Ядро - как библиотека функций
правитьЕсли вы хотите, чтобы отдельные части вашего алгоритма можно было применять в дальнейшем при построении новых программ, то единственный реальный путь к этому – вычленить претендующие на многократное использование функциональные компоненты вашей программы и оформить их в виде модулей. В результате такой деятельности формируется библиотека функций.
Пополняя библиотеку, уделяют внимание тестированию отдельных модулей, их единообразному описанию (интерфейсу), но, как правило, совершенно не беспокоясь о сохранении работоспособности прежнего состава библиотеки. Причины для беспокойства действительно нет, так как поступающие модули обычно настолько слабо связаны с остальными компонентами, что их появление не может как либо повредить соседям по библиотеки. Это происходит от того, что модули из библиотеки играют только подчиненную роль: разработчик новой программы самостоятельно пишет ведущую часть, которая время от времени обращается к таким модулям для решения частных подзадач.
Надежность ядра
правитьКак мы видим оформление в виде ядра, некоторых библиотек функций необходимо в первую очередь, для надежного повторного использования уже отлаженных и оттестированных алгоритмов. Причем надежность тут первично. Именно для обеспечения надежности, отказываются от простого дублирования кода. Наличие дублирования есть самая главная причина проведения рефакторинга.
Мы можем ввести два термина:
- Безболезненность для окружения. Метод изменения содержимого программного фонда называется безболезненным для окружения, если его применение не влечет за собой необходимости редактирования существовавших ранее текстов программ и других первичных материалов.
- Безболезненность для работоспособности. Метод изменения содержимого программного фонда называется безболезненным для работоспособности, если его применение не может нарушить работоспособность отлаженных ранее конкретных конфигураций программ и других первичных материалов. Необходимое условие безболезненности для работоспособности – безболезненность для окружения.
Таким образом, выделенные и оттестированные функции составляют ядро, и его использование является безболезненным как для окружения, так и для работоспособности.
Ядро - это не только библиотека функций
правитьНо полноценное ядро - это не только библиотека функций. При разработке архитектуры ядра анализируется не только как должны работать собственно функции библиотеки, но и то как их будет использовать сторонний разработчик. Кроме того, архитектура ядра предполагает разделение кода на так называемые слои. Когда один слой отвечает за математические расчеты, второй за работу с графикой и интерфейсом пользователя, третий с бизнес логикой, четвертый с базой данных. При этом само ядро реализует только минимум функций, но при этом должно обеспечить независимость и концепцию слоев ПО. Таким образом, архитектура ядра налагает ряд ограничений на то, как этим ядром будет пользоваться сторонний разработчик.
Так например, примеры хорошо реализованных ядер можно найти почти исключительно только в реализации известных операционных систем (см. w:en:Kernel (computing)), или на уровне "железа" в реализации работы процессора (см. w:Микроархитектура). А многие т.н. движки, необоснованно называют ядром того или иного программного комплекса. Они, как правило, не выполняют никакой архитектурной роли, за исключением библиотеки функций, и могут рассматриваться лишь как SDK для разработки ПО.
Архитектура ядра с кольцами защиты
правитьЗдесь мы рассмотрим понятие кольца защиты, и её применение к современной трёхуровневой архитектуре.
Кольца защиты обеспечивают информационную безопасность и отказоустойчивость на уровне аппаратного разделения системного и пользовательского уровней привилегий. Структуру привилегий можно изобразить в виде нескольких концентрических кругов. В этом случае системный режим (нулевое кольцо), обеспечивающий максимальный доступ к ресурсам, является внутренним кругом, тогда как режим пользователя с ограниченным доступом — внешним. Традиционно семейство микропроцессоров x86, начиная с x386 обеспечивает четыре кольца защиты.
На практике процессор программируется в защищенном режиме определенным образом. Для каждой локальной задачи выделяется свое локальное адресное пространство (память). В каждый момент времени в определенном регистре процессора может быть указатель только на одну из задач. Поэтому задача работает только в своем адресном пространстве и не может физически иметь доступ к другим локальным задачам. Для смены задач осуществляется т.н. переключение задач. Каждая задача имеет т.н. уровень привилегий дискриптора (DPL). Этот уровень как раз и указывает в каком кольце находится задача. Основные правила защиты по привилегиям сводятся к следующим:
- Данные из задачи (программы) с некоторым уровнем привилегий могут быть получены только программой того же или более внутреннего уровня
- Программа с некоторым уровнем привилегий может быть вызвана только программой того же или более внешнего уровня, причем вызов программы другого уровня должен осуществляться не непосредственно, а через шлюз вызова
- Все команды, управляющие механизмами защиты могут использоваться только в программах нулевого уровня, что исключает вмешательство в организацию операционной системы со стороны прикладных программ
Таким образом, данные находящиеся на более низком уровне с более высоких физически получить нельзя. С более высокого уровня можно вызвать программы только более низкого уровня, и то через т.н. шлюз. Сам шлюз готовится на более низком уровне, и определяет по сути, что с помощью его можно вызвать. И только обладая таким шлюзом программа более высокого уровня может вызвать программу более низкого уровня. По этой причине очень многие функции ядра операционной системы нельзя вызвать из клиентских программ, и для работы с ними нужно писать драйверы.
Вот такого рода защиту и должно обеспечивать полноценное ядро. Это, например, может означать, что сторонние разработчики не могут напрямую вызвать функцию ядра (этим ядро и отличается от библиотеки функций). Также сторонние разработчики не могут получить никаких данных из ядра, кроме тех которые непосредственно предоставляет само ядро. Но главное, управление программным ходом выполняет исключительно ядро, и при необходимости может блокировать любые клиентские подпрограммы (например, те которые работаю ошибочно или не согласно принятой архитектуре), а клиентским программам для осуществления вызовов специально предоставляет callback-функции или что тоже самое работает через события (аналог вызова через шлюз).
Таким образом, такого рода ядро реализует:
- так называемый каркас архитектуры для управления ходом выполнения клиентских приложений (об этом мы поговорим в следующей статье каркас архитектуры)
- внутри себя реализует библиотеку функций (внутренний SDK - для разработчика ядра)
- часть функций, как правило в определенной "обертке" (API), из своей библиотеки, через механизм защиты (например, путем callback-функций) предоставляет клиентским приложениям
Теперь понимая, что для надежности и более четкой архитектуры нужно изолировать тем или иным образом слои приложений. Только если выше говорилось о системных слоях между операционной системой и клиентскими приложениями, то мы можем пойти далее, и изолировать слои в самом клиентском приложении.
И этих слоев как минимум два, т.н. клиент-серверная архитектура. Так сложилось, что для работы с данными повсеместно используются реляционные базы данных и, как правило, в серьезных приложениях используют или Oracle или MS SQL. Вся работа с данными преимущественно происходит посредством работы на языке SQL. Более того, как правило в хорошо разработанной архитектуре, запрещается какое-либо прямое обращение к базе данных, и вся работа с базой данных ведется посредством вызова только хранимых процедур, а уже в них на SQL так или иначе ведется работа с данными. Поэтому слой базы данных уже традиционно выделен и фактически отделен. Единственно плохо когда некоторые архитектуры, пользуясь возможностями языков программирования, прямо обращаются в серверу базы данных. В тоже время программировать пользовательский интерфейс на языке SQL невозможно. Для этого используют новейшие объектно-ориентированные языки.
Но можно пойти и еще дальше, пример более общей структуры представляет трёхуровневая архитектура. В ней также отделен сервер базы данных, но аналогично технологии MVC происходит разделение бизнес-логики и визуализации. Мы уже говорили о проблемах реализации классического MVC, но сам принцип разделения остается важным, хотя и может быть реализован более качественно. Но если в технологии MVC разделение касалось на уровне одного класса с его подклассами, то в трёхуровневой архитектуре речь идет о выделении всей визуализации в отдельную самостоятельную программу, а выделению отдельной программы (сервера) бизнес-логики. Понятно, что такое физическое разделение можно осуществить только тогда, когда логически в программе строго все было уже разделено или согласно технологии MVC, или другими более современными способами.
Тогда уже на уровне развертывания ПО, можно в зависимости от необходимости комбинировать самостоятельные компоненты ПО так или иначе. Например, можно совместить сервер бизнес-логики и сервер базы данных, а на клиентские машины поставить только программы визуализации - получая таким образом тонкого клиента. Или наоборот, совместить программы визуализации и сервер бизнес-логике на клиентских машинах, отделив только сервер базы данных - получив таким образом толстого клиента.