Читаем Объектно-ориентированный анализ и проектирование с примерами приложений на С++ полностью

void display(float, SensorName, unsigned int id = 0);

Сейчас, после того как мы уточнили этот элемент нашей архитектуры, можно составить новую диаграмму классов, отражающую механизм покадровой обработки (рис. 8-14).

<p>8.3. Эволюция </p>

Планирование релизов

Рассмотрев несколько сценариев работы системы и убедившись в правильности стратегических решений, можно начинать планирование процесса разработки. Разобьем работу на ряд этапов, результат каждого из которых будет являться основой для последующего:

• Разработка программы, обладающей минимальными функциональными свойствами и осуществляющей мониторинг только одного датчика.

• Создание иерархии датчиков.

• Создание классов, ответственных за управление изображением на экране.

• Создание классов, ответственных за работу пользовательского интерфейса.

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

Мы не будем подробно останавливаться на реализации данной версии, поскольку это в большей степени тактическая задача, а перейдем сразу к дальнейшим релизам. При этом мы откроем для себя некоторые интересные особенности процесса разработки.

Механизм датчиков

Мы уже видели, как при разработке архитектуры системы постепенно наполнялись содержанием и приобретали устойчивые формы ее ключевые абстракции, в том числе классы датчиков. Руководствуясь эволюционным подходом к разработке, будем строить следующую версию на основе первой, минимальной.

На данном этапе разработки иерархия классов-датчиков, представленная на рис. 8-4, остается без изменений. Мы, однако, должны уточнить местонахождение некоторых полиморфных операций, чтобы добиться как можно более высокой степени общности классов в иерархии. Ранее, например, мы описали требования к операции currentValue, принадлежащей абстрактному базовому классу Sensor. Более полно конструкцию данного класса можно определить на C++ следующим образом:

class Sensor {public:

Sensor(SensorName, unsigned int id = 0);virtual ~Sensor();virtual float currentValue = 0;virtual float rawValue() = 0;SensorName name() const;unsigned int id() const;

protected:...};

Этот класс включает в себя чисто виртуальные функции-члены, и поэтому является абстрактным.

Отметим, что конструктор класса сообщает экземпляру его имя и номер. Это сделано для обеспечения возможности динамического определения типа датчика, а также для того, чтобы удовлетворить одно из требований к системе, согласно которому каждый из датчиков имеет постоянный адрес доступа в оперативной памяти. Эти детали реализации системы можно скрыть, вычисляя адрес в памяти через тип датчика и его идентификационный номер.

После того, как мы добавили новые свойства к классу датчиков, можно вернуться немного назад и упростить объявление функции DisplayManager::display, которая теперь может иметь только один аргумент, а именно ссылку на объект класса Sensor. От остальных аргументов можно отказаться, так как объект класса, производного от sensor, сам выдаст информацию о своем типе и идентификационном номере.

Это казалось бы незначительное изменение крайне желательно, так как если не стремиться к упрощению внешнего интерфейса классов, то со временем наша система будет все больше и больше страдать от перегруженности протоколов взаимодействия между ними.

Объявление подкласса CalibratingSensor основывается на базовом классе Sensor:

class CalibratingSensor : public Sensor {public:

CalibratingSensor(SensorName, unsigned int id = 0);virtual ~CalibratingSensor();void setHighValue(float, float);void setLowValue(float, float);virtual float currentValue();virtual float rawValue() = 0;

Перейти на страницу:

Похожие книги

Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript

Данная книга посвящена программированию игр с помощью ActionScript. Здесь вы найдете подробные указания, необходимые для создания самых разных игр – аркад, головоломок, загадок и даже игровых автоматов. В тексте приведены исходные коды программ и детальные, доступно изложенные инструкции. Базовые принципы программирования ActionScript рассматриваются на примере игр, однако вы без труда сможете применить полученные знания и для разработки неигровых проектов, таких как Web-дизайн и реклама. Рекомендации Гэри Розенцвейга помогут вам не только придумывать занимательные игры и размещать их на Web-сайте, но и оптимизировать скорость их работы, а также защищать свои творения от несанкционированного копирования. Представленный в книге код несложно изменить для использования в других программах.Книга предназначена для широкого круга читателей – создателей анимационных роликов, художников-оформителей, программистов и разработчиков Web-сайтов. Издание может также выступать в качестве практического пособия по изучению ActionScript.

Гэри Розенцвейг

Программирование, программы, базы данных / Программирование / Книги по IT