Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Графические соглашения

Обсуждение

 

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

 

 

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

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

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

Используемые для классов и объектов графические соглашения совместимы со стандартом, установленным методом BON (Nerson и Walden). В методе BON, (Business Object Notation) предназначенном для использования в интерактивных CASE-средствах и в документации, классы отображаются в виде пузырьков, растягиваемых по вертикали, показывающих компоненты класса, инварианты и другие свойства.(О BON см. библиографические заметки и лекцию 9 курса "Основы объектно-ориентированного проектирования")

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

Трудно удержаться от того, чтобы не процитировать следующий ненаучный аргумент, заимствованный из рецензии Ian Graham на книгу по ОО-анализу, использующую другие графические соглашения:

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

 

Ссылки и простые значения

 

Важный синтаксический вопрос - должны ли мы установить синтаксическое различие при работе со ссылками и простыми значениями. Как отмечалось, присваивание и эквивалентность имеют различный смысл для ссылок и значений развернутых типов. Но синтаксис этого не различает, - в обоих случаях используются одинаковые символы (:=, =, /=). Не опасно ли это? Не предпочтительнее ли использовать различные наборы символов, напоминая тем самым, что они имеют разный смысл?

Два набора символов использовались в языке Simula 67. Немного изменив нотацию для совместимости с настоящей книгой (в языке Simula reference сокращается до ref), в Simula можно записать объявление сущности ссылочного типа C так:

 

x: reference C

 

Ключевое слово reference указывает, что экземпляры x будут ссылками. Рассмотрим объявления:

 

m, n: INTEGER

x, y: reference C

 

Нотация Simula, используемая для операций с простыми и ссылочными типами, приведена в таблице.

Операция Операнды развернутых типовОперанды-ссылки Присваивание m:= nx:- y Проверка на равенство m = nx == y Проверка на неравенство m /= nx =/= y Таблица 8.3. Нотация в стиле Simula для операций со ссылками и значениями развернутых типов

 

Соглашения Simula лишены неоднозначности. Почему бы их не сохранить? К сожалению, эти соглашения могут служить примером благих намерений, приносящих скорее вред, нежели пользу. Проблемы начинаются в прозаической области поиска ошибок. Два набора символов похожи, - это провоцирует синтаксические ошибки, подобные использованию := вместо :-.

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

Но самый важный аспект соглашений Simula в том, что он не оставляет выбора: для ссылок нет доступной конструкции, дающей семантику значений. Представляется разумным для сущностей a и b ссылочного типа иметь два множества операций:

[x]. a:- b для ссылочных присваиваний и a == b сравнения ссылок;

[x]. a:= b для присваивания путем копирования (эквивалент a := clone (b) или a.copy (b) в нашей нотации) и a = b для сравнения объектов (эквивалент нашего equal (a, b)).

Но за одним исключением, Simula поддерживает только первое множество операций. Если необходимы операции второго множества (copy или clone, сравнение объектов), придется написать специальные подпрограммы для каждого целевого класса. Исключением является TEXT, для которого Simula предлагает оба множества операций.

Кстати, при дальнейшем анализе идея предоставления двух множеств операций для всех ссылочных типов не кажется уже столь разумной. Это бы означало, что тривиальная описка - использование := вместо :-, теперь уже не обнаруживалась бы компилятором, а приводила бы к результату, далекому от ожидаемого, например, к клонированию вместо ссылочного присваивания.

Как результат этого анализа, нотация этой книги использует соглашения, отличные от тех, что используются в Simula: одни и те же символы применимы для развернутых и ссылочных типов с различной семантикой. Эффекта семантики значений можно достигнуть для объектов ссылочного типа при использовании предопределенных подпрограмм, применимых для всех типов:

[x]. a:= clone (b) или a.copy (b) для объектного присваивания;

[x]. equal (a, b) для сравнения объектов на идентичность всех полей.

Эта нотация существенно отличается от нотации, применяемой для их ссылочных двойников, (:= и =, соответственно) что снижает риск появления недоразумений.

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

[x]. "Выражайте различные концепции с помощью различных символов".

Но другие силы, доминирующие в нашей нотации, требуют:

[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, а не (:= и =).

 

<== предыдущая лекция | следующая лекция ==>
Инкапсуляция действий со ссылками | Форма операций клонирования и эквивалентности
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 261; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.017 сек.