М. Фаулер, К. Скотт - UML Основы (1114905), страница 24
Текст из файла (страница 24)
Общедоступные элементы могут быть использованы любым другим классом, а закрытые элементы— только классом-владельцем. Несмотря на это в каждом языке программирования существуют свои собственные правила. Хотя многие языки используют такие термины, как «общедоступный», «закрытый» и взащищенный» (ргоВес|ет|), в разных языках они имеют различное содержание. Эти различия невелики, однако они приводят к Глава б.
Диаграммы классов; дополнительные понятия недоразумениям, особенно тех из нас, кто использует в своей работе более одного языка программирования. Язык ПМ1. пытается решить эту проблему, не устраивая при этом жуткую путаницу. По существу, в рамках языка ()М? для любого атрибута или операции можно указать индикатор видимости. Для этой цели можно использовать любой подходящий маркер, смысл которого определяется тем или иным языком программирования. Однако язык СМЬ предлагает три (довольно трудно запомнить) отдельных обозначения для этих вариантов видимости: «+» (общедоступный), »-» (закрытый) и»№» (защищенный). Мне бы очень хотелось поскорее закончить на этом, но, к сожалению, разработчики при построении диаграмм используют видимость в своей собственной интерпретации. Поэтому, чтобы действительно понять некоторые из основных различий, существующих между моделями, необходимо понимать трактовку видимости в различных языках программирования.
Итак, сделаем глубокий вдох и погрузимся во мрак. Мы начнем с языка программирования С++, поскольку он является основой стандартного использования языка (УМЬ: ° Общедоступный элемент является видимым в любом месте программы и может быть вызван любым объектом в системе. ° Закрытый элемент может быть использован только тем классом, в котором он определен. ° Защищенный элемент может быть использован только а) тем классом, в котором он определен, или б) подклассом этого класса.
Рассмотрим класс Клиент и его подкласс Индивидуальный Клиент. Рассмотрим также объект Мартин, который является экземпляром класса Индивидуальный Клиент. Мартин может использовать любой общедоступный элемент любого объекта в системе. Мартин может также использовать любой закрытый элемент класса Индивидуальный Клиент. Мартин не может использовать никакой закрытый элемент, определенный внутри класса Клиент, однако он может использовать защищенные элементы класса Клиент и защищенные элементы класса Индивидуальный Клиент.
Теперь обратимся к языку Ята11Са!)с. В этом языке все переменные экземпляра являются закрытыми, а все операции — общедоступными. Однако закрытость в языке Ята11Са1(с имеет не тот же самый смысл, что в языке С++. В системе, написанной на Ята)1Са1)с, Мартин может иметь доступ к любой переменной экземпляра своего собственного объекта, независимо от того, где была определена эта переменная экземпляра: в Клиенте или в Индивидуальном Клиенте.
Таким образом, закрытость в языке Ята11Са))с имеет тот же смысл, что и защищенность в языке С++. Тем не менее, было бы слишком просто закончить на этом. Видимость Вернемся опять к языку С++. Пусть имеется еще один экземпляр класса Индивидуальный Клиент с именем Кендалл. Кендалл может иметь доступ к любому элементу Мартина, который был определен как часть класса Индивидуальный Клиент, независимо от того, является ли он общедоступным, закрытым или защищенным.
Кендалл может также иметь доступ к любому защищенному или общедоступному элементу Мартина, который был определен в классе Клиент. Однако в языке ВшаПСаПс Кендалл не может получить доступ к закрытым переменным экземпляра Мартина, а только к общедоступным операциям Мартина. В языке С++ доступ к элементам других объектов вашего собственного класса обеспечивается в той же степени, что и к вашим собственным элементам. В языке БтаПСаПс безразлично, принадлежит ли другой объект к тому же самому классу или нет; вам все равно доступны только общедоступные элементы другого объекта.
Язык Лама похож на язык С++ в том, что он поддерживает свободный доступ к элементам других объектов одного и того же класса. В языке Лача введен дополнительный уровень видимости, получивший название «пакет» (рас)саяе). Элемент с видимостью внутри пакета может быть доступен только в экземплярах других классов этого же пакета. Продолжая эту тему, следует отметить, что все это вовсе не так просто; в языке Лача несколько по иному определяется защищенная видимость. В Лача защищенный элемент может быть доступен не только подклассам, но и любому другому классу того же самого пакета, к которому относится класс-владелец. Это означает, что в языке дача защищенная видимость является более общедоступной, чем пакетная. Язык Лача разрешает также помечать классы как общедоступные или пакетные. Общедоступные элементы общедоступного класса могут использоваться любым классом, который импортирует пакет, содержащий исходный класс.
Пакетный класс может быть использован только другими классами в том же самом пакете. Последний штрих в эти тонкости добавляет язык С++. В языке С++ какой-либо метод или класс может быть определен как «дружественный» (Уг1епс() для класса. Такой дружественный элемент обладает полным доступом ко всем элементам класса. Отсюда пошло высказывание: «в С++ друзья прикасаются к закрытым частям друг друга».
При определении видимости пользуйтесь правилами того языка, на котором вы программируете. С какой бы точки зрения вы не смотрели на модель 1)МЬ, следует с осторожностью относиться к смыслу маркеров видимости и осознавать, что их смысл может меняться от языка к языку. По моему мнению, обычно видимость изменяется в процессе кодирова- ния. Поэтому не следует определять ее слишком рано.
Пакеты и кооперации Один из старейших вопросов методологии разработки программного обеспечения: как разбить большую систему на небольшие подсистемыу Мы задаем этот вопрос, поскольку чем больше становятся системы, тем труднее разбираться в них и во вносимых в них изменениях. Структурные методы использовали функциональную декомпозицию, согласно которой вся система в целом представляется как одна функция и разбивается на подфункции, которые в свою очередь тоже разбиваются на подфункции и т. д, Эти функции похожи на варианты использования в объектно-ориентированной системе в том, что функции представляют собой действия, выполняемые системой в целом.
В прежние времена процесс и данные рассматривались отдельно друг от друга. Другими словами, помимо функциональной декомпозиции существовала также структура данных. Она имела второстепенное значение, хотя некоторые методы информационных технологий группировали записи данных в предметные области и формировали матрицы, чтобы показать взаимосвязь функций и записей данных. Именно с этой точки зрения мы можем оценить те огромные изменения, которые произвели объекты.
Разделение процесса и данных осталось в прошлом, функциональная декомпозиция тоже, однако старейший вопрос по-прежнему все еще существует. Одна из идей заключается в группировке классов в блоки более высокого уровня. Эта идея, применяемая самым произвольным образом, 11В Глава 7.
Пакеты и кооперации проявляется во многих объектных методах. В языке СМ1. такой механизм группировки получил название пакет (рас)тане). Пакеты Идея пакета может быть применена не только к классам, но и к любому другому элементу модели. Без некоторых эвристических процедур группировка классов может оказаться произвольной. Одной из них, которую я считаю самой полезной и которая повсеместно используется в языке УМЕ, является завиеимоеть. Я использую термин диаграмма пакетов по отношению к диаграмме, которая содержит пакеты классов и зависимости между ними. Строго говоря, диаграмма пакетов является всего лишь разновидностью диаграммы классов, на которой показаны только пакеты и зависимости.
Сам я использую эти диаграммы очень часто, поэтому и называю их диаграммами пакетов. Однако следует помнить, что этот термин введен мною, а не является официальным именем диаграммы в языке СМ1. Между двумя элементами существует зависимость, если изменения в определении одного элемента могут повлечь за собой изменения в другом. Что касается классов, то характер зависимостей может быть самым различным: один класс посылает сообщение другому; один класс включает другой класс как часть своих данных; один класс ссылается на другой как на параметр некоторой операции. Если класс меняет свой интерфейс, то любое сообщение, которое он поеылает, может оказаться ошибочным.
В идеальном случае только изменения в интерфейсе класеа должны оказывать влияние на другие классы. Искусство проектирования больших систем включает в себя минимизацию зависимостей; таким образом влияние изменений уменьшается, а для изменения системы требуются меньшие усилия. В языке ПМ1. имеются разнообразные виды зависимостей, каждый из которых обладает самостоятельной семантикой и етереотипом. По моему мнению, намного проще начинать с зависимости без стереотипа и использовать более конкретные виды зависимостей только по мере необходимости. На рис. 7.1 изображены классы предметной области, моделирующие бизнес-систему и сгруппированные в два пакета: Заказы и Клиенты. Оба пакета являются частью пакета предметной области в целом.
Приложение Сбора Заказов имеет зависимости с обоими пакетами предметной области. Пользовательский Интерфейс Сбора Заказов имеет зависимости с Приложением Сбора Заказов и А%'Т (средством разработки графического интерфейса пользователя в языке )атта). Пакеты Пакет ЗееисииОсть Рис.