Основы объектно-ориентированного программирования - Бертран Мейер
0/0

Основы объектно-ориентированного программирования - Бертран Мейер

Уважаемые читатели!
Тут можно читать бесплатно Основы объектно-ориентированного программирования - Бертран Мейер. Жанр: Прочая околокомпьтерная литература. Так же Вы можете читать полную версию (весь текст) онлайн книги без регистрации и SMS на сайте Knigi-online.info (книги онлайн) или прочесть краткое содержание, описание, предисловие (аннотацию) от автора и ознакомиться с отзывами (комментариями) о произведении.
Описание онлайн-книги Основы объектно-ориентированного программирования - Бертран Мейер:
Фундаментальный учебник по основам объектно-ориентированного программирования и инженерии программ. В книге подробно излагаются основные понятия объектной технологии – классы, объекты, управление памятью, типизация, наследование, универсализация. Большое внимание уделяется проектированию по контракту и обработке исключений, как механизмам, обеспечивающим корректность и устойчивость программных систем.В книге Бертрана Мейера рассматриваются основы объектно-ориентированного программирования. Изложение начинается с рассмотрения критериев качества программных систем и обоснования того, как объектная технология разработки может обеспечить требуемое качество. Основные понятия объектной технологии и соответствующая нотация появляются как результат тщательного анализа и обсуждений. Подробно рассматривается понятие класса - центральное понятие объектной технологии. Рассматривается абстрактный тип данных, лежащий в основе класса, совмещение классом роли типа данных и модуля и другие аспекты построения класса. Столь же подробно рассматриваются объекты и проблемы управления памятью. Большая часть книги уделена отношениям между классами – наследованию, универсализации и их роли в построении программных систем. Важную часть книги составляет введение понятия контракта, описание технологии проектирования по контракту, как механизма, обеспечивающего корректность создаваемых программ. Не обойдены вниманием и другие важные темы объектного программирования – скрытие информации, статическая типизация, динамическое связывание и обработка исключений. Глубина охвата рассматриваемых тем делает книгу Бертрана Мейера незаменимой для понимания основ объектного программирования.
Читем онлайн Основы объектно-ориентированного программирования - Бертран Мейер

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 104 105 106 107 108 109 110 111 112 ... 188

if full then

error := Overflow

else

check representation /= Void end

representation.put (x); error := 0

end

Здесь читатель может думать, что вызов в else ветви: representation.put(x) потенциально не безопасен, поскольку ему не предшествует тест: (representation /=Void). Но, исследуя текст класса, можно понять, что из условия (full = false) следует положительность capacity, откуда, в свою очередь, следует, что representation не может быть Void. Это важное и не совсем тривиальное свойство, которое должно быть частью инварианта реализации класса. Фактически, с полностью установленным инвариантом реализации следует переписать инструкцию проверки следующим образом:

check

representation_exists: representation /= Void

-- Поскольку предложение representation_exists истинно, когда

-- full ложно, что следует из инварианта реализации.

end

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

Механизмы утверждений, рассмотренные в этой лекции, помимо того, что они дают преимущества все вещи делать правильно с самого начала, они еще позволяют найти то, что сделано неверно. Используя параметры компиляции можно включить проверку, и сделать инструкцию check реально проверяемой в период выполнения. Если все предположения выполняются, то проверка не оказывает воздействия на процесс вычислений, но, если вы ошиблись, и предположения не выполняются, то в точке их нарушения будет выброшено исключение и процесс остановится. Тем самым появляется возможность быстрого обнаружения содержательных ошибок. Механизм checking - включения проверок будет вкратце рассмотрен в дальнейшем.

Инварианты и варианты цикла

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

Трудности циклов

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

Но с мощностью приходят и риски. У циклов дурная слава, - их трудно заставить работать правильно. Типичными для циклов являются:

[x]. Ошибки "больше-меньше" (выполнение цикла слишком много или слишком мало раз).

[x]. Ошибки управления пограничными ситуациями, например пустыми структурами. Цикл может правильно работать на больших массивах, но давать ошибки, когда у массива один элемент или он вообще пуст.

[x]. Ошибки завершения ("зацикливание") в некоторых ситуациях.

Бинарный поиск - один из ключевых элементов базового курса "Введение в информатику" (Computer Science 101) - хорошая иллюстрация "коварства" циклов даже в относительно тривиальной ситуации. Рассмотрим целочисленный, упорядоченный по возрастанию массив t с индексами от 1 до n. Используем алгоритм бинарного поиска для ответа на вопрос: появляется ли целое x среди элементов массива. Если массив пуст, ответ должен быть "нет", если в массиве ровно один элемент, то ответ "да" тогда и только тогда, когда элемент массива совпадает с x. Суть бинарного поиска, использующего упорядоченность массива, проста: вначале x сравнивается со средним элементом массива, если есть совпадение, то задача решена, если x меньше среднего элемента, то поиск продолжается в верхней половине массива, в противном случае - в нижней половине. Каждое сравнение уменьшает размер массива вдвое. Ниже представлены четыре попытки реализации этой простой идеи. К несчастью, все они содержат ошибки. Вам предоставляется случай поупражняться в поиске ошибок и установить, в какой ситуации каждый из алгоритмов не работает нужным образом.

Напомню, t @ m означает элемент массива t с индексом m. Знак операции // означает деление нацело, так что 7 // 2 и 6 // 2 дают значение 3. Синтаксис цикла будет дан ниже, но он должен быть и так понятен. Предложение from вводит инициализацию цикла.

BS1

from

i := 1; j := n

until i = j loop

m := (i + j) // 2

if t @ m <= x then

i := m

else

j := m

end

end

Result := (x = t @ i)

BS2

from

i := 1; j := n; found := false

until i = j and not found loop

m := (i + j) // 2

if t @ m < x then

i := m + 1

elseif t @ m = x then

found := true

else

j := m - 1

end

end

Result := found

BS3

from

i := 0; j := n

until i = j loop

m := (i + j + 1) // 2

if t @ m <= x then

i := m + 1

else

j := m

end

end

if i >= 1 and i <= n then

Result := (x = t @ i)

else

Result := false

end

BS4

from

i := 0; j := n + 1

until i = j loop

m := (i + j) // 2

if t @ m <= x then

i := m + 1

else

j := m

end

end

if i >= 1 and i <= n then

Result := (x = t @ i)

else

Result := false

end

Таблица 11.3.Четыре (ошибочных) попытки реализации бинарного поиска

Сделаем циклы корректными

Разумное использование утверждений может помочь справиться с такими проблемами. Цикл может иметь связанное с ним утверждение, так называемый инвариант цикла (loop invariant), который не следует путать с инвариантом класса. Он может также иметь вариант цикла (loop variant), являющийся не утверждением, а, обычно целочисленным выражением. Совместно, инвариант и вариант позволяют гарантировать корректность цикла.

Для понимания этих понятий необходимо осознать, что цикл - это способ вычислить некоторый результат последовательными приближениями (successive approximations).

Рассмотрим тривиальный пример вычисления максимума в целочисленном массиве, используя очевидный алгоритм:

maxarray (t: ARRAY [INTEGER]): INTEGER is

-- Максимальное значение массива t

require

t.capacity >= 1

local

i: INTEGER

do

from

i := t.lower

Result := t @ lower

until i = t.upper loop

i := i + 1

Result := Result.max (t @ i)

end

end

В разделе инициализации i получает значение нижней границы массива, а сущность Result - будущий результат вычислений - значение первого элемента. Предусловие гарантирует существование хотя бы одного элемента в массиве. Производя последовательные итерации в цикле, мы достигаем верхней границы массива, увеличивая на каждом шаге i на 1, и заменяя Result значением элемента t @ i, если этот элемент больше чем Result. Для нахождения максимума двух целых используется функция max, определенная для класса integer: a.max(b) возвращает максимальное значение из a и b.

1 ... 104 105 106 107 108 109 110 111 112 ... 188
На этой странице вы можете бесплатно читать книгу Основы объектно-ориентированного программирования - Бертран Мейер бесплатно.
Похожие на Основы объектно-ориентированного программирования - Бертран Мейер книги

Оставить комментарий

Рейтинговые книги