Масштабируемость системы

И это опять вопрос о структуре системы (который очень тесно связан с масштабируемостью).

С одной стороны, если вы встроите таймер в саму управляющую программу, вы дадите на нее дополнительную нагрузку. Ей придется выполнять не только свои обычные обязанности (работа с базой данных, отображение данных для оператора, и так далее), но еще и обслуживать таймеры. На небольшую, простую систему это, скорее всего, не окажет никакого влияния. Но если вы станете расширять вашу систему до масштабов предприятия, то столкнетесь с тем, что все дополнительные вычисления сосредоточены в едином месте. Где бы вы ни встретили фразу «сосредоточены в едином месте», вы сразу же должны обратить внимание на проблемы с масштабируемостью. Возникают несколько существенных проблем при встраивании таймеров в управляющую программу.

  • Масштабируемость — управляющая программа должна содержать свой таймер для каждой двери; чем больше дверей, тем больше таймеров.
  • Безопасность — если после открытия двери перестанет работать подсистема связи с замком, то вы останетесь с открытой дверью.
  • Возможность обновления — если новый тип двери потребует другие параметры для таймера (например, вместо простых команд «открыть» и «закрыть», ей требуется передать несколько команд для нескольких устройств с различной задержкой), то вам придется обновлять управляющую программу целиком.

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

Рассмотрим следующий возможный вариант. Нужен ли вам отдельный процесс, который управляет таймерами и общается с драйверами дверного замка? И я снова отвечу — нет. Вопросы масштабируемости и безопасности, рассмотренные в предыдущем примере, в данном случае неприменимы (вы же, конечно, распределите этот менеджер таймеров между несколькими процессорами, так, что масштабирован он будет хорошо, и, так как он будет работать на том же процессоре, что и драйвер, можно исключить и вопрос об ошибках связи). Однако проблема с возможностью обновления остается. Но появляется еще и новая проблема — функциональная группировка. Вот что я здесь имею в виду. Таймер тесно связан с аппаратным обеспечением. У вас может быть простая аппаратура, для которой вы сами пишете таймер, или более сложная с уже встроенным таймером. Плюс к этому, у вас может быть и очень сложное оборудование, требующее многофазовые управляющие последовательности. Имея отдельный менеджер, работающий с таймерами, вы будете зависеть от тонкостей аппаратного обеспечения. Проблема здесь в том, что вы распределяете информацию об аппаратном обеспечении между двумя процессами, не получая при этом никаких преимуществ. Если бы это были драйверы файловой системы и диска, то получалось бы, что у вас один процесс отвечает за чтение данных с диска, а другой — за запись. Поэтому никаких преимуществ вы не получаете, и даже наоборот, усложняете драйвер, потому что теперь два процесса должны координировать свои действия друг с другом, чтобы получить доступ к аппаратному обеспечению.

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

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