Абстракция через спецификацию
Абстракция через спецификацию позволяет абстрагироваться от процесса вычислений описанных в теле процедуры, до уровня знания того, что данная процедура делает. Это достигается путем задания спецификации, описывающей эффект ее работы, после чего смысл обращения к данной процедуре становится ясным через анализ этой спецификации, а не самого тела процедуры. Мы пользуемся абстракцией через спецификацию всякий раз, когда связываем с процедурой некий комментарий, достаточно информативный для того, чтобы иметь возможность работать без анализа тела процедуры.
Спецификации важны для достижения требуемой модульности программы. Абстракция используется для декомпозиции программы на модули. Однако взятая в отдельности абстракция является малопонятной. Без какого-либо описания мы не можем ни сказать, что она собой представляет, ни отличить ее от одной из своих реализаций. В качестве такого описания и выступает спецификация.
Спецификация описывает соглашение между разработчиками и пользователями. Разработчик берется написать модуль, а пользователь соглашается не полагаться на знания о том, как именно этот модуль реализован, т.е. не предполагать ничего такого, что не было бы указано в спецификации. Такое соглашение позволяет разделить анализ реализации от собственно использования программы. Спецификации дают возможность создавать логические основы, позволяющие успешно "разделять и властвовать".
При анализе спецификации для уяснения смысла обращения к процедуре нужно придерживаться двух правил:
1. После выполнения процедуры можно считать, что выполнено конечное условие. Выполнение конечного условия при соблюдении начальных условий - это собственно то, ради чего и построена процедура. Если это процедура поиска максимального значения в массиве, то конечное условие - факт, что максимальный элемент найден. Если это процедура вычисления квадратного корня, то конечное условие - нахождение квадратного корня.
2. Можно ограничиться только той информацией, которую подразумевает конечное условие.
Эти правила демонстрируют два преимущества абстракции через спецификацию. Первое состоит в том, что программисты, использующие данную процедуру, не обязаны знакомиться с ее телом. Следовательно, им не нужно уяснять, например, подробности алгоритма отыскания квадратного корня, устанавливая действительно ли возвращенный результат искомое число.
Второе правило показывает, что на самом деле имеем дело с абстракцией: абстрагируясь от тела процедуры, можно не обращать внимания на несущественную информацию. Именно такое "игнорирование" информации и отличает абстракцию от декомпозиции. Конечно, анализируя тело процедуры можно извлечь некоторое количество информации, не следующей из конечного условия (как, например, то, что найденный элемент первый или последний в рассмотренном выше примере). В спецификации подобная информация о возвращаемом результате отбрасывается.
Абстракции через параметризацию и через спецификацию являются мощным средством для создания программ. Они позволяют определить два вида абстракций: процедурную абстракцию и абстракцию данных. В общем случае каждая процедурная абстракция и абстракция данных используют оба способа.
Например, абстракцию SQRT (извлечение квадратного корня) можно сравнить с операцией: она абстрагирует отдельное событие или задачу. Мы будем ссылаться к абстракциям такого рода как к процедурным абстракциям. Отметим, что абстракция SQRT включает в себя как абстракцию через параметризацию, так и абстракцию через спецификацию. Процедурная абстракция - мощное средство. Она позволяет расширить заданную некоторым языком программирования виртуальную машину новой операцией. Такое расширение полезно, когда мы работаем с задачами, которые можно представить в виде набора независимых функциональных единиц. Однако часто удобно к такой новой виртуальной машине добавить несколько объектов данных с новыми типами.
Поведение объектов данных наиболее естественно представлять в терминах набора операций, применимых к данным объектам. Такой набор включает в себя операции по созданию объектов, получению информации о них и их модификации.
Например, при работе с целыми числами используются обычные арифметические операции, но при работе со стеком нужны другие операции, такие как POP (изъять из стека), PUSH (положить в стек).
Таким образом, абстракция данных (или тип данных) состоит из набора объектов и набора операций, характеризующих поведение этих объектов.