Основы объектно-ориентированного программирования
Шрифт:
Ингредиенты вычисления
При поиске правильной архитектуры ПО критическим является вопрос о модуляризации: какие критерии нужно использовать при выделении модулей наших программ?
Чтобы верно ответить на него, нужно сравнить соперничающих кандидатов.
Базисный треугольник
Три силы вступают в игру, когда мы используем программу для выполнения каких-либо вычислений
Выполнить программную систему - значит использовать некоторые процессоры для применения некоторых действий к некоторым объектам.
Рис. 5.1.
Процессоры - это вычислительные устройства (физические или виртуальные), выполняющие команды. Процессор может быть фактической единицей обработки (например, ЦПУ компьютера), процессом обычной операционной системы или одним ее "потоком" для многопоточной ОС.
Действия - это операции, производящие вычисления. Точная форма рассматриваемых нами действий будет зависеть от уровня детальности анализа. Например, на уровне оборудования действия являются операциями машинного языка, на аппаратно-программном уровне - операторами языка программирования, а на уровне программной системы можно рассматривать в качестве действия каждый большой шаг сложного алгоритма.
Объекты - это структуры данных, к которым применяются действия. Некоторые из этих объектов - структуры данных, построенные вычислением для своих собственных целей, - являются внутренними и существуют только во время вычисления, другие (содержащиеся в файлах, базах данных и других постоянных хранилищах) являются внешними и могут пережить вычисления, в которых используются.
Процессоры будут важны при обсуждении параллельных вычислений, в которых одновременно могут выполняться несколько подвычислений. В этой лекции мы ограничиваемся непараллельными или последовательными вычислениями, проводимыми одним (остающимся за рамками рассмотрения) процессором.
Таким образом, остаются действия и объекты. Дуализм между действиями и объектами - тем, что система делает, и тем, с чем она это делает - это популярная тема в разработке ПО.
[x]. Замечание о терминологии. Для обозначения каждого из этих двух аспектов имеются соответствующие синонимы: слово данные будет использоваться как синоним слова объекты, а вместо слова действие мы, следуя обычной практике, будем говорить о функциях системы.
[x]. Термин "функция" также не лишен недостатков, поскольку при обсуждении ПО он используется по крайней мере в двух смыслах: математическом и в смысле ПО как подпрограмма, возвращающая некоторый результат. Но, не боясь неоднозначности, мы будем использовать фразу "функции системы", требуемую здесь.
[x]. Причина, по которой мы используем это слово, а не "действие" - чисто грамматическое удобство от использования соответствующего прилагательного, например во фразе "функциональная декомпозиция". Слово "действие" не имеет соответствующего производного прилагательного. Другим термином, чье значение в нашем обсуждении эквивалентно значению слова "действие", является слово "операция".
Всякое обсуждение, связанное с программированием, должно учитывать оба аспекта: объект и функцию, это относится и к проектированию программной системы. Но есть один вопрос, при ответе на который между ними нужно выбирать - это вопрос данной лекции: что является критерием выделения
Ответ на этот вопрос демонстрирует различие между ОО-подходом и другими методами. При традиционных подходах каждый модуль строится вокруг некоторой единицы функциональной декомпозиции - некоторой части действия. В отличие от них, ОО-метод строит каждый модуль вокруг некоторого типа объектов.
Нетрудно догадаться, что в этой книге развивается именно этот подход. Но нам не следует принимать ОО-декомпозицию на веру лишь потому, что она подразумевается названием этой книги, или потому, что она является "вещью-в-себе", которую просто необходимо делать.
В последующих разделах мы проанализируем аргументы, обосновывающие использование типов объектов в качестве основы модуляризации, а начнем с исследования достоинств и ограничений традиционных не ОО-методов. Затем мы попытаемся получить ясное представление о том, что на самом деле означает слово "объект" для проектирования ПО, хотя полный ответ, требующий некоторых дополнительных теоретических рассуждений, появится только в следующей лекции.
Мы должны также отложить до следующей лекции урегулирование старинной и грозной битвы, ставшей темой нашего обсуждения - Войны Объектов и Функций. Пока же мы подготовим кампанию опорочивания функций в качестве базиса декомпозиции, и, соответственно, восхваления объектов для достижения этих целей. И все-таки нам не следует забывать сделанное выше наблюдение, в конечном счете, в нашем решении проблем должно найтись место, как объектам, так и функциям, хотя и не на равных основаниях. Для установления нового мирового порядка необходимо определить роли граждан первого и второго сорта.
Функциональная декомпозиция
Вначале мы рассмотрим достоинства и ограничения традиционного подхода, использующего функции в качестве основы архитектуры программных систем. Это не только приведет нас к пониманию того, почему требуется еще кое-что - объектная технология, но и поможет избежать некоторых методологических ловушек, таких как преждевременное упорядочение операций, которым, как известно, грешат даже опытные разработчики ОО-ПО.
Непрерывность
Ключевой проблемой при ответе на вопрос: "вокруг чего следует структурировать системы: вокруг функций или вокруг данных?" является проблема расширяемости, более точно - цель, названная непрерывностью в предшествующем обсуждении. Как вы помните, метод проектирования удовлетворяет этому критерию, если он приводит к устойчивой архитектуре, обеспечивающей объем изменений в проекте, соразмерный объему изменений в спецификации.
Обеспечение непрерывности - это главная забота при рассмотрении реального жизненного цикла программных систем, включающего не только производство приемлемой первоначальной версии, но и эволюцию системы на протяжении долгого времени. Большинство систем подвергаются многочисленным изменениям после их первоначальной поставки. Поэтому всякая модель разработки ПО, которая рассматривает только период, предшествующий этой поставке, и игнорирующая последующую эру изменений и пересмотров, весьма далека от реальной жизни, как те романы, которые заканчиваются женитьбой героя на героине в тот момент, когда, как каждый знает, только и должно начинаться самое интересное.