Объектно-ориентированное программирование на C++


Декомпозиция и абстракция


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

На этапе декомпозиции задачи на подзадачи следует придерживаться трех правил:

1.каждая подзадача должна иметь один и тот же уровень рассмотрения,

2.каждая подзадача может быть решена независимо,

3.полученные решения могут быть объединены вместе, позволяя решить исходную задачу.

Декомпозиция - весьма полезный инструмент для решения задач в различных областях. Однако при неумелом использовании она не может принести желаемого эффекта. К числу наиболее распространенных проблем относится ситуация, когда объединение решений подзадач не приводит к решению исходной. Как правило, такое случается для больших и плохо понимаемых задач.

Пример. Группа авторов создает пьесу, причем каждый из них пишет текст для одного персонажа. Очевидно, что хотя каждый из авторов и справится со своей задачей, о смысле готового произведения говорить не приходится.

Поэтому стадии декомпозиции должен предшествовать этап абстракции.

Абстракция подразумевает собой процесс изменения уровня детализации программы. Когда мы абстрагируемся от проблемы, мы предполагаем игнорирование ряда подробностей с тем, чтобы свести задачу к более простой.

После чего декомпозиция такой задачи окажется более простой по сравнению с исходной.

Пример. Группа авторов предварительно оговаривает сюжет пьесы, смысл отдельных диалогов и т.п.

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

Как уже упоминалось, процесс абстракции может быть выражен как некоторое обобщение. Оно позволяет рассматривать различные предметы, так как если бы они были эквивалентны за счет выделения существенных атрибутов от несущественных. Одним из первых шагов на пути понятия процесса абстракции мы все проделали еще в первых классах школы, когда от конкретной задачи "3 яблока + 2 груши = ? фруктов" перешли к осознанию более абстрактного выражения "3+2 = ?", а затем и вовсе "X+Y = ?".




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

Сравним, например, два фрагмента кода

int i,a[100];

:

int iaMax = 0;

int aMax = a[0];

for (i=1; i<100; i++)

{

if (a[i]>aMax)

{

aMax = a[i];

iaMax = i;

}

}

:
int i,a[100];

:

int iaMax = 99;

int aMax = a[99];

for (i=98; i>=0; i--)

{

if (a[i]>aMax)

{

aMax = a[i];

iaMax = i;

}

}

:

На уровне абстракции, определенном языком высокого уровня, приведенные фрагменты отличаются друг от друга: первый фрагмент, отыскивает первый максимальный элемент в массиве (если их несколько), второй - последний. Однако оба они написаны для выполнения одной и той же функции - отыскать максимальное значение в целочисленном массиве a и индекс такого элемента. Если необходимо выполнение этого требования, то очевидно, что приведенные фрагменты не находятся на требуемом уровне абстракции.

Было бы гораздо удобнее обладать некоторым мощным набором примитивов для манипуляции со структурами данных. Так, если бы существовали примитивы GetMaxValue и GetMaxIndex, тогда рассматриваемая задача легко реализуется

aMax = GetMaxValue (a);

iMax = GetMaxIndex (a);

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


Содержание раздела