Читаем Основы объектно-ориентированного программирования полностью

[x]. "Не создавайте разработчику лишних проблем".

[x]. "Тщательно взвешивайте все "за и против" любой новинки, обращая особое внимание на безопасность и качество".

[x]. "Убедитесь, что общие операции могут быть выражены в простой и ясной форме". Применение этого принципа требует особой тщательности, поскольку проектировщик языка может ошибаться в своих оценках того, что же является наиболее общим случаем. Но в данной ситуации все кажется проще. Для сущностей развернутого типа (таких как INTEGER) присваивание и сравнение значений представляются наиболее употребительными операциями. Для ссылок, в то же время, ссылочное сравнение и присваивание используется чаще, чем клонирование, копирование и сравнение объектов. Поэтому в обоих случаях предпочтительнее использовать := и = для фундаментальных операций.

[x]. "Для сохранения компактности и простоты языка вводите новые обозначения, только если это абсолютно необходимо". Это справедливо в частности для приведенного примера - существующая нотация работает и не существует опасности путаницы.

[x]. "Если вы знаете, что существует риск возникновения недоразумений между двумя возможностями, то соответствующие нотации должны различаться очевидным образом". Так что необходимо избегать использования символов, близких по написанию (:- и :=), но с различной семантикой.

Еще одна причина играет роль в данном случае, хотя она включает механизм, пока еще не изученный. В последующих лекциях мы познакомимся с родовыми или универсальными классами, такими как LIST [G], где G, известно как формальный родовой параметр, представляющий произвольный тип. Такой класс может манипулировать сущностями типа G и использовать их в присваиваниях и проверках на равенство. Клиенты, нуждающиеся в использовании такого класса, должны позаботиться о создании типа, служащего в качестве фактического родового параметра. Например, они могут использовать LIST [INTEGER] или LIST [POINT]. Как показывают эти примеры, фактический родовой параметр может быть развернутого типа, как в первом случае, так и ссылочного типа - во втором случае. В подпрограммах такого родового класса, если a и b имеют тип G, то часто полезно использовать присваивания в форме a := b или тесты в форме a = b с намерением получить семантику значений, когда фактический параметр принадлежит развернутому типу, такому как INTEGER, и ссылочную семантику - для ссылочного типа, такого как POINT.

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

В таких случаях, правила, определенные выше, гарантируют желаемое дуальное поведение, что было бы недостижимо, если бы требовался различный синтаксис для двух видов семантики. С другой стороны, если во всех случаях требуется единая семантика, то и это достижимо: такое поведение может быть только семантикой значений (так как семантика ссылок не имеет смысла для развернутых типов); поэтому в соответствующих подпрограммах следует использовать clone (или copy) и equal, а не (:= и =).

Форма операций клонирования и эквивалентности

Форма вызова подпрограмм clone и equal является стилевой особенностью, которая может вызвать удивление. На первый взгляд нотация:


clone (x)

equal (x, y)


выглядит не слишком объектно-ориентированной. Догматичное следование принципу "ОО-стиля вычислений" из предыдущей лекции предполагает другую форму (См. "Объектно-ориентированный стиль вычислений", лекция 7):


x.twin -- twin это двойник - клон.

x.is_equal (y)


В первой версии нотации так и делалось, однако возникла проблема пустых ссылок. Вызов компонента вида x.f (...) не может быть корректно выполнен в случае пустого x во время выполнения. В этом случае вызов инициирует исключение, которое повлечет аварийное завершение всей системы, если в соответствующем классе не предусмотрена обработка исключений. Поскольку во многих случаях x может быть действительно пустой ссылкой, то это означало бы, что каждый вызов twin должен предусматривать охрану и выглядеть так:


if x = Void then

z := Void

else

z := x.twin

end


Соответственно, реализация вызова is_equal должна выглядеть (and then является вариантом and. См. "Нестрогие булевы операции", лекция 13):


if

((x = Void) and (y = Void)) or

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

Похожие книги

Об интеллекте
Об интеллекте

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

Сандра Блейксли , Джефф Хокинс , Джеф Хокинс , Сандра Блэйксли

Зарубежная компьютерная, околокомпьютерная литература / Технические науки / Прочая компьютерная литература / Образование и наука / Книги по IT