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

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

Читать бесплатно Бертран Мейер - Основы объектно-ориентированного программирования. Жанр: Прочая околокомпьютерная литература издательство неизвестно, год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

Open_error: INTEGER is 2

Read_error: INTEGER is 3

которые позволяют записывать условные инструкции вида

[U2]

if code = Successful then ...

или инструкции выбора

[U3]

inspect

code

when Successful then

...

when ...

end

Но такой перебор значений констант утомляет. Следующий вариант записи действует так же, как [U1]:

[U4]

Successful, Open_error, Read_error: INTEGER is unique

Спецификатор unique, записанный вместо буквального значения в объявлении атрибута-константы целого типа, указывает на то, что это значение выбирает компилятор, а не сам разработчик. При этом условная инструкция [U2] и оператор выбора [U3] по-прежнему остаются в силе.

Каждое unique-значение в теле класса положительно и отличается от других. Если, как в случае [U4], константы будут описаны вместе, то их значения образуют последовательность. Чтобы ограничить значение code этими тремя константами, в инвариант класса можно включить условие

code >= Successful; code <= Read_error

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

Значения, заданные как unique, следует использовать только для представления фиксированного набора возможных значений. Если допустить его пополнение, то это приведет к необходимости внесения изменений в тексты инструкций, подобных [U3]. В общем случае для классификации не рекомендуется использовать unique-значения, так как ОО-методология располагает лучшими приемами решения этой задачи. Данный выше пример является образцом правильного обращения с описанным механизмом. Правильными можно считать и объявления цветов семафора: green, yellow, red: INTEGER is unique; нот: do, re, mi, ...: INTEGER is unique. Объявление savings, checking, money_market: INTEGER is unique возможно будет неверным, поскольку различные финансовые инструменты, список которых здесь приведен, имеют различные свойства или допускают различную реализацию. Более удачным решением в этом случае, пожалуй, станут механизмы наследования и переопределения.

Объединим сказанное в форме правила:

Принцип дискриминации

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

Хотя объявление unique-значений напоминает определение перечислимых типов (enumerated type) языков Pascal и Ada, оно не вводит новые типы, а только целочисленные значения. Дальнейшее обсуждение позволит объяснить разницу подходов.

Обсуждение

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

Инициализация: подходы языков программирования

Проблема, решаемая в этой лекции, - это общая проблема языков программирования: как работать с глобальными константами и разделяемыми объектами, в частности, как выполнять их инициализацию в библиотеках компонентов?

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

Последнюю задачу можно свести к более простой: как разделять переменные булевого типа и согласованно их инициализировать? Свяжем с глобальным объектом p или группой глобальных объектов, нуждающихся в одновременной инициализации, булеву переменную, скажем, ready, истинную, если и только если инициализация проведена. Тогда любому обращению к p нетрудно предпослать инструкцию

if not ready then

"Создать или вычислить p"

ready := True

end

Теперь проблема инициализации касается только ready - еще одного глобального объекта, который необходимо инициализировать значением False.

Как же решается эта задача в языках программирования? С момента их появления в этом плане почти ничего не менялось. В блочно-структурированных языках, среди которых Algol и Pascal, типичным было описание ready как глобальной переменной на верхнем синтаксическом уровне; ее инициализация производилась в главной программе. Но такая техника непригодна для библиотек автономных модулей.

В языке Fortran, позволяющем независимую компиляцию подпрограмм (что придает им известную автономность), можно поместить все глобальные объекты в общий блок (common block), идентифицируемый по имени. Всякая подпрограмма, обращающаяся к общему блоку, должна содержать такую директиву:

COMMON /common_block_name/ data_item_names

При этом возникают две проблемы:

[x]. Две совокупности подпрограмм могут использовать одноименные общие блоки, что приведет к конфликту, если одной из программ понадобится как первый, так и второй блок. Смена имени блока вызовет трудности у других программ.

[x]. Как инициализировать сущности общего блока, такие как ready? Из-за отсутствия инициализации по умолчанию, ее нужно выполнять в особом модуле, называемом блоком данных (block data unit). В Fortran 77 допускаются именованные модули, что позволяет разработчикам объединять глобальные данные разных общих блоков. При этом есть немалый риск несогласованности инициализации и объявления глобальных объектов.

Принцип решения этой задачи в языке C по сути не отличается от решения Fortran 77. Признак ready нужно описать как "внешнюю" переменную, общую для нескольких "файлов" (единиц компиляции языка). Объявление переменной с указанием ее значения может содержать только один файл, остальные, используя директиву extern, подобную COMMON в Fortran 77, лишь заявляют о необходимости доступа к переменной. Обычно такие определения объединяют в "заголовочные" (header) .h-файлы, которые соответствуют блоку данных в Fortran. При этом наблюдаются те же проблемы, отчасти решаемые утилитами make, призванными отслеживать возникающие зависимости.

Решение может быть близко к тому, что предлагают модульные языки наподобие Ada или Modula 2, подпрограммы которых можно объединять в модули более высокого уровня. В Ada эти модули называют "пакетами" (package). Если все подпрограммы, использующие группу взаимосвязанных глобальных объектов, собраны в одном пакете, то соответствующие признаки ready можно описать в этом же пакете и здесь же выполнить их инициализацию. Однако этот подход (применимый также в C и Fortran 77) не решает проблему инициализации автономных библиотек. Еще более деликатный вопрос связан с тем, как поступать с глобальными объектами, разделяемых подпрограммами разных независимых модулей. Языки Ada и Modula не дают простого ответа на этот вопрос.

Механизм "однократных" методов, сохраняя независимость классов, допускает контекстно-зависимую инициализацию.

Строковые константы

Строковые константы (а точнее, разделяемые строковые объекты) объявляются в языках программирования в манифестной форме с использованием двойных кавычек. Это находит отражение в правилах языка, и как следствие любой компилятор предполагает присутствие в библиотеке класса STRING. Это - своего рода компромисс между "полярными" решениями.

[x]. STRING рассматривается как встроенный тип, каким он является во многих языках программирования. Это означает введение в язык операций над строками: конкатенации, сравнения, выделения подстроки и других, что усложняет язык. Преимуществом введения такого класса является возможность снабдить его операции точными спецификациями, благодаря утверждениям, и способность порождать от него другие классы.

[x]. STRING рассматривается как обычный класс, создаваемый разработчиком. Тогда задавать его константы в манифестной форме [S1] уже нельзя, от разработчиков потребуется соблюдение формата [S2]. Кроме того, данный подход препятствует оптимизации компилятором таких операций, как прямой доступ к символам строки.

Поэтому строки STRING, как и массивы ARRAY, ведут "двойную жизнь", принимая вид предопределенного типа при задании констант и оптимизации кода, и становясь классом, когда речь заходит о гибкости и универсальности.

Перейти на страницу:

Бертран Мейер читать все книги автора по порядку

Бертран Мейер - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


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

Отзывы читателей о книге Основы объектно-ориентированного программирования, автор: Бертран Мейер. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*