- •1.Введение
- •1.1.Декомпозиция и абстракция
- •1.2.Абстракция
- •1.2.1.Абстракция через параметризацию
- •1.2.2.Абстракция через спецификацию
- •1.2.3.Виды абстракций
- •3.Процедурная абстракция
- •3.2.Спецификации
- •3.3.Спецификации процедурных абстракций
- •3.4.Реализация процедур
- •3.5.Более обобщенные процедуры
- •3.6.Создание процедурных абстракций
- •3.7.Заключение
- •4.Абстракции данных
- •4.1.Спецификации для абстракций данных
- •4.2.1.Реализация на языке clu
- •4.2.2.Замечания по поводу операций up и down
- •4.3.Использование абстракций данных
- •4.4.Реализация полиномов
- •4.5.Пояснения для понимания реализаций
- •4.5.1.Функция абстракции
- •4.5.2.Инвариант представления
- •4.6.3.Сохранение инварианта представления
- •4.5.4.Изменяемые представления
- •4.6.Параметризованные абстракции данных
- •4.7.Списки
- •4.8.Упорядоченные списки
1.2.3.Виды абстракций
Абстракции через параметризацию и через спецификацию являются мощными средствами создания программ. Они позволяют нам определить три различных вида абстракций: процедурную абстракцию, абстракцию данных и абстракцию через итерацию. В общем случае каждая процедурная абстракция, абстракция через данные и абстракция через итерацию используют оба способа.
Например, абстракцию sqrtможно сравнить о операцией: она абстрагирует отдельное событие или задачу. Мы будем ссылаться к абстракциям такого рода как кпроцедурным абстракциям.Отметим, что абстракция sqrtвключает в себя как абстракцию через параметризацию, так и абстракцию через спецификацию.
Процедурная абстракция является мощным средством. Она позволяет нам расширить заданную некоторым языком программирования виртуальную машину новой операцией. Такой вид расширения наиболее полезен в том случае, когда мы работаем с задачами, которые легко представить в виде набора независимых функциональных единиц. Однако часто оказывается более удобным добавить к виртуальной машине несколько объектов данных с новыми типами.
Поведение объектов данных наиболее естественно представлятьвтерминах набора операций, применимых к данным объектам. Такой набор включает в себя операции по созданию объектов, получению информации от них и, возможно, их модификации. Например, операции pushи popпринадлежат к классу операций, имеющих смысл при работе со стеками, в то время как для работы с целыми числами используются обычные арифметические операции. Таким образом,абстракция данных(илитип. данных)состоит из набора объектов и набора операций, характеризующих поведение этих объектов.
В качестве примера рассмотрим мультинаборы (multisets). Мультинаборы сходны с обычными наборами, за исключением того, что элемент может входить в мультинабор несколько раз. Операции для работы с подобными мультинаборами включают в себя операции empty, insert, delete, number_ofи size.Эти операции создают пустой мультинабор, удаляют и добавляют в него элементы, вычисляют, сколько раз данный элемент входит в мультинабор и сколько всего элементов содержится в мультинаборе. Данные операции могут быть реализованы в языке программирования через соответствующие процедуры. Программисты, работающие с мультинаборами, не должны беспокоиться о том, каким образом эти процедуры реализованы. Для них операции empty, insert, delete, number_ofи sizeявляются абстракциями, определяемыми операторами типа
The size of the multi.set insert (s, e) is equal to size (s) + I (Размер мультинабора insert (s, e)равен размеру size (s) + 1)
For all e, the number, of timese occurs in the multi_ set empty ( )is0. (Для всех eчисло вхождений eв пустой мультинабор empty ( ) равно 0.)
Важно отметить, что каждый из этих операторов работает сразу с несколькими операциями. Мы не приводим независимые определения каждой операции, но скорее определяем их через взаимосвязи. Этот акцент на взаимосвязях между операциями и делает абстракцию данных существенно отличной от набора процедур. Важность этого отличия обсуждается на протяжении всей книги.
В дополнение к процедурным абстракциям и абстракциям данных мы рассмотрим такжеабстракцию через итерацию.Абстракция через итерацию дает возможность не рассматривать информацию, не имеющую прямого отношения к управляющему потоку или циклу. Типичная абстракция итерации позволяет нам обрабатывать все элементы мультинабора без накладывания каких-либо ограничений на последовательность обработки.
Далее мы покажем, как осуществлять декомпозицию программы на базе абстракции через итерацию. Акцент будет делаться на абстракции данных. Мы считаем, что, хотя процедурные абстракции и абстракции через итерацию и играют существенную роль, организация процесса программирования начинается, как правило, с абстракции данных.
Последующие несколько глав посвящены трем перечисленным видам абстракций —что они из себя представляют, как описывается их поведение и как происходит их реализация. Мы начнем с описания языка программирования CLU,специально созданного для работы по методике, описанной в данной книге, поддерживающего каждый из описываемых видов абстракций. Абстракции на языке CLUреализуются сравнительно просто, поэтому в главах с 3по 6используется именно этот язык. В седьмой главе мы обсудим, как реализовать абстракции на языке Паскаль.
В последней части книги рассматривается использование абстракций при составлении программ. Обсуждаются этапы составления программ, их проектирование и реализация. Книга включает в себя ряд практических советов, помогающих реилль проблемы, возникающие при составлении реальных программ.
Дополнительная литература
Boehnn, Barry W,, 1976. Software engineering. IEEE Transactions on Computers C-25 (12): 1226—1241.
Brooks, Frederick P., Jr., 1975. The Mythical Man-Month, Reading, Mass,.: Addison-Wesley Publishing Co.
Buxton, John M., Peter Naur, and Brian Randell (eds.), 1976. Software engineering concepts and techniques. In Proceedings of the NATO Conference (New York: Petrocelli/Charter).
Gries, David (ed.), 1978. Part 1: viewpoints on programming. In Programming Methodology, A Collection of Articles by Members of IF IP W02.3 (New York: Springer-Verlag), pp. 7—74.
Упражнения
I.I.Опишите знакомую вам иерархию абстракции.1.2.Выберите написанную или используемую вами процедуру и рассмотрите, каким образом в ней реализована абстракция через спецификацию и через параметры.
Еще более важным является эффект, оказываемый данным стилем программирования. В объектно-ориентированном языке внимание фокусируется на объектах, их смысловом значении и их поведении. Эта особенность хорошо сочетается с методологией программирования, описываемой в данной книге. В этой методологии абстракции данных, состоящие из объектов данных и операций для работы с ними, являются наиболее важным средством организации программ.
Упражнения
2.1.Вычисление наибольшего общего делителя способом последовятельного вычитания (рис. 2.1)является недостаточно эффективным. Переделайте функциюgcdс использованием деления.2.2.Создайте процедуру с заголовком
тах = proc (a: array [int]) returns (int)
Процедура maxдолжна возвращать максимальное значение в а. Вы можете считать, что массив а является непустым.
2.3.Проиллюстрируйте вызов процедуры gcdна рис. 2.1диаграммой по аналогии с рис. 2.5.
2.4.Массив, передаваемый в качестве аргумента процедуре remove, dupis на рис. 2.5,содержит дублирующие элементы 1и 3.Почему эти элементы не показаны на рис. 2,5,в?
2.5.Разработайте процедуру, которая определяет, является ли заданная символьная строка палиндромом. (Палиндром читается одинаково слева и справа, например «deed».) 2.6.Напишите процедуру с заголовком
combine =z proc (a: array [int 1, comb: proctype (int, int) returns (int)) returns (int)
Она должна объединять все элементы массива а, используя аргумент процедурыcomb.Например, combine (a, int$add)складывает все элементы массива а. Вы можете считать, что массив а содержит по крайней мере 2элемента.
2.7.Напишите процедуру, просматривающую поток и возвращающую из него последующее слово, где слово представляет собой любую комбинацию символов, исключая пробелы и разделители строк. Вы можете считать, что поток позиционцрован по первому символу слова.
2.8.Реализуйте процедуру, пропускающую пробелы в потоке. Она должна возвращать поток, позиционированный по первому символу, отличному от пробела, или символу конца файла, если символы, отличные от пробела, отсутствуют,