Джим Арлоу, Айла Нейштадт - UML 2 и Унифицированный процесс. Практический объектно-ориентированный анализ и проектирование (1037782), страница 33
Текст из файла (страница 33)
Операции уровня классаможно рассматривать как применяемые к самому классу.Невозможно вызвать операциюэкземпляра, не имея в распоряжении экземпляра класса. Безусловно, это означает, что нельзя использовать операции, область действия которых – экземпляр, для создания объектовэтого класса: никогда не получится создать первый объект.Инициировать операции классаможно, даже не имея экземпляра класса; это идеально подходит для операций создания объектов.7.7. Создание и уничтожение объектовКонструкторы – это специальные операции, создающие новые объекты.Область их действия – класс.172Глава 7. Объекты и классыКонструкторы – это специальные операции, создающие новые экземпляры классов. Эти операции должны иметь область действия – класс.Если бы они были уровня экземпляра, не было бы возможности создать первый экземпляр класса.Конструкторы – забота проектирования.
Обычно их не показываютна аналитических моделях.В разных языках программирования действуют разные стандартыименования конструкторов. Абсолютно универсальный подход – называть конструктор просто create(…) (создать). Это делает понятнымназначение данной операции. Однако языки Java, C# и C++ требуют,чтобы имя конструктора совпадало с именем класса.У класса может быть несколько конструкторов с одинаковыми именами, но с разным набором параметров. Конструктор без параметров называют применяемым по умолчанию конструктором (default con+structor).
Параметры конструктора можно использовать для инициализации значений атрибутов в момент создания объекта.На рис.7.16 показан простой пример класса BankAccount (банковскийсчет). При каждом создании объекта BankAccount в качестве параметрав его конструктор должно передаваться значение типа String. Эта строка используется для задания атрибута accountNumber (номер счета) (например, значение “XYZ001002”). Тот факт, что конструктору класса BankAccount необходим параметр, говорит о том, что создать объект BankAccount, не определив этот параметр, нельзя.
Это гарантирует задание атрибута accountNumber каждого объекта BankAccount в момент созданияобъекта. Это очень хороший стиль.В аналитических моделях обычно не занимаются конструкторами(и тем более деструкторами). Они не имеют ни влияния, ни отношенияк бизнессемантике класса. Если всетаки есть желание обозначитьоперации создания, можно ввести операцию create() без параметровкак структурный нуль. Или можно указать только параметры, имеющие в перспективе существенное значение.Когда дело дойдет до детального проекта, необходимо будет определить имя, типы параметров и возвращаемый тип каждой операции(см.
раздел 17.4). Сюда входит и явное описание конструктора и деструктора.Уничтожение объекта не такая простая операция, как его создание.В разных ОО языках программирования семантика уничтожения объBankAccountBankAccount+create( accNumber : String )+BankAccount( accNumber : String )универсальное имя конструкторастандарт Java/C#/C++Рис. 7.16. Именование конструктора7.7. Создание и уничтожение объектов173екта разная. Более подробно создание и уничтожение объектов рассматриваются в следующих двух разделах.7.7.1. Конструкторы – пример класса ClubMemberПример класса ClubMember (член клуба) (рис.
7.17) показывает обычноеприменение атрибутов и операций уровня класса. Этот класс описываетнекий член клуба. Атрибут numberOfMembers (количество членов) – закрытый (private) атрибут класса типа int. Следовательно, этот атрибутиспользуется совместно всеми объектами класса ClubMember. Его значение для каждого из этих объектов будет одинаковым.ClubMember!membershipNumber : String!memberName : String!numberOfMembers : int = 0+create( number : String, name : String )+getMembershipNumber() : String+getMemberName() : String!incrementNumberOfMembers+decrementNumberOfMembers+getNumberOfMembers() : intРис. 7.17. Применение атрибутов и операций уровня классаПри создании атрибута numberOfMembers ему присваивается начальноезначение, равное нулю. Далее, если бы это был атрибут экземпляра,каждый объект при создании получал бы собственную копию этого атрибута.
Однако область действия этого атрибута – класс. Значит, существует только одна его копия, и эта единственная копия инициализируется только один раз. Когда именно это происходит, зависит отязыка реализации. Мы должны знать лишь то, что атрибут инициализируется со значением нуль при запуске программы.Предположим, что в операции create(...) происходит вызов операциикласса incrementNumberOfmembers() (увеличить число членов). Как можноожидать из ее имени, эта операция увеличивает значение атрибута класса numberOfMembers. При каждом создании экземпляра класса numberOfMembers увеличивается на единицу.
В класс введен счетчик! С помощьюоперации класса getNumberOfMembers() (получить количество членов)можно запросить значение атрибута numberOfMembers. Данная операциявозвращает число, равное количеству созданных объектов ClubMember.7.7.2. Деструкторы – пример класса ClubMemberДеструкторы – это специальные операции, которые «наводят порядок»при уничтожении объектов.174Глава 7. Объекты и классыЧто происходит, если программа создает и уничтожает объекты ClubMember? Очевидно, что значение атрибута numberOfMembers быстро потеряет смысл. Исправить эту ситуацию можно, введя в класс операциюдля уменьшения значения атрибута numberOfMembers (рис.
7.17) и обеспечив ее вызов при каждом уничтожении экземпляра класса ClubMember.В некоторых ОО языках программирования есть специальные операции уровня экземпляра, называемые деструкторами, которые автоматически вызываются в момент уничтожения объекта. Например, в С++деструктор всегда имеет форму ~ИмяКласса (списокПараметров). В С++операция уничтожения гарантированно вызывается в момент уничтожения объекта.В Java есть аналогичная возможность: каждый класс имеет операциюпод названием finalize(), которая вызывается при окончательном уничтожении объекта. Но сама программа явно не уничтожает объекты.Этим занимается автоматический сборщик мусора.
Вам известно, чтоfinalize() будет вызван, но вы не знаете, когда это произойдет! Конечно,это не подходит для нашего простого приложения со счетчиком. Здесьприходится самостоятельно уменьшать значение атрибута numberOfMembers, вызывая операцию уровня класса decrementNumberOfMembers(), когда работа с объектом завершена и он отправляется в сборщикмусора.C# имеет аналогичную Java семантику уничтожения, только операция называется Finalize().7.8. Что мы узналиВ этой главе были представлены основные сведения по классам и объектам, которые используются далее в книге.
Классы и объекты – этостроительные блоки ОО систем, поэтому важно всесторонне и детальноих понимать.Мы узнали следующее:•Объекты – это образующие единое целое элементы, сочетающие в себе данные и функции.•Инкапсуляция – данные, находящиеся внутри объекта, скрыты.Манипулировать ими можно, только инициируя одну из функцийобъекта.••Операции – это спецификации функций объекта, создаваемыево время анализа.•Методы – это реализации функций объекта, создаваемые во время реализации.Каждый объект – это экземпляр класса.
Класс определяет общиехарактеристики, присущие всем объектам этого класса.7.8. Что мы узнали•У каждого объекта есть следующие характеристики:••••175Идентичность – уникальность существующего объекта: вы используете объектные ссылки для однозначного указания на конкретный объект.• Состояние – значимый набор значений атрибутов и отношенийобъекта в определенный момент времени.• Состояние образуют наборы только таких значений атрибутов и отношений, которые обуславливают существенное семантическое отличие от других возможных наборов. Например, объект BankAccount: balance < 0, state = Overdrawn; balance > 0,state = InCredit.• Переход состояний – перемещение объекта из одного значимого состояния в другое.• Поведение – сервисы, предлагаемые объектом другим объектам:• моделируется в виде набора операций;• вызов операции может генерировать переход состояния.Совместная работа объектов генерирует поведение системы.• Взаимодействие включает в себя обмен сообщениями между объектами – при получении сообщения инициируется соответствующая операция; это может привести к переходу состояний.Нотация объектов в UML – в каждой пиктограмме объекта двеячейки.• В верхней ячейке находится имя объекта и/или имя класса,и то и другое должно быть подчеркнуто.• Имена объектов записываются в стиле lowerCamelCase.• Имена классов записываются в стиле UpperCamelCase.• Никаких специальных символов, знаков препинания или сокращений.• Имя объекта отделяется от имени класса одним двоеточием.• Нижняя ячейка содержит имена и значения атрибутов, разделяемые знаком равенства.• Имена атрибутов записываются в стиле lowerCamelCase.• Типы атрибутов могут быть представлены, но обычно для краткости их опускают.Класс определяет характеристики (атрибуты, операции, отношения и поведение) ряда объектов.• Каждый объект – это экземпляр только одного класса.• Разные объекты одного класса имеют одинаковый набор атрибутов, но значения этих атрибутов могут быть разными.
Разныезначения атрибутов обусловливают разное поведение объектоводного класса. Например, сравните попытку снять $100 с объек176Глава 7. Объекты и классыта BankAccount, кредит которого превышен, с попыткой снять$100 с объекта BankAccount, на котором есть $200 кредита.•Существует множество классификаций мира. Правильный выбор схемы классификации – один из ключей к успешному ООанализу.•Отношение создания экземпляра между классом и одним из егообъектов можно показать с помощью зависимости, обозначенной стереотипом «instantiate»:•••отношения объединяют сущности;•отношение зависимости показывает, что изменение сущностипоставщика оказывает влияние на сущностьклиент.При создании экземпляра с использованием класса в качествешаблона создается новый объект.•Большинство ОО языков программирования предоставляютспециальные операции, конструкторы, которые вызываются,когда необходимо создать объект – конструкторы создаютили инициализируют объекты; область действия конструкторов – класс (они принадлежат классу).•Некоторые ОО языки программирования предоставляют специальные операции, деструкторы, которые вызываются приуничтожении объекта – деструкторы «наводят порядок» после уничтожения объектов.Нотация классов в UML:•В ячейке имени размещается имя класса, записанное в стилеUpperCamelCase:•••никаких сокращений, знаков препинания или специальныхсимволов.Ячейка атрибутов – у каждого атрибута есть:•видимость – управляет доступом к характеристикам класса;•имя (обязательно) – записывается в стиле lowerCamelCase;•кратность – коллекции, например [10]; неопределенные значения, например [0..1];•тип;•у атрибутов могут быть стереотипы и помеченные значения.Ячейка операций – у каждой операции может быть:•видимость;•имя (обязательно) – записывается в стиле lowerCamelCase;•список параметров (имя и тип каждого параметра);•у параметра может быть применяемое по умолчанию значение (не обязательно);7.8.