- •Проектирование информационных систем
- •Вопрос 1. Обязанности, методы, взаимодействия
- •Вопрос 2. Шаблоны
- •Information Expert
- •Шаблон Information Expert
- •Шаблон Creator
- •Шаблон Low Coupling
- •Шаблон High Cohesion
- •Шаблон Controller
- •Вопрос 3. Реализация прецедентов
- •Пример: Реализация прецедентов для данной итерации разработки pos системы тт
- •Проектное решение: makeNewSale
- •Выбор класса-контроллера
- •Проектное решение: enterItem
- •Проектное решение: endSale
- •Проектное решение: makePayment
- •Проектное решение: startup
- •Проектное решение: store-create
- •Подключение уровня интерфейса пользователя к уровню предметной области
Проектное решение: enterItem
Системная операция enterItemначинается с ввода кассиром кода товараitemIDи количества покупаемых единиц. Приведем полное описание этой операции.
ОП 2: enterItem
Операция
|
enterItem (itemID: itemID, quantity: integer )
|
Ссылки
|
Прецеденты: Оформление продажи
|
Предусловия
|
Инициирована продажа |
Постусловия
|
Инициализированы атрибуты экземпляра s.
|
Диаграмма взаимодействия должна обеспечивать выполнение постусловии описания системной операции enterItem. Проектное решение принимается на основе шаблоновGRASP.
Выбор класса-контроллера
Класс-контроллер должен обрабатывать сообщение системной операции enterItem. Согласно шаблонуController, в качестве контроллера будем использовать классRegister, как и для операцииmakeNewSale.
Отображение описания товара и его цены
В соответствии с шаблоном Model-ViewSeparation, специальные объекты (такие, какRegisterиSale) не должны взаимодействовать с элементами уровня интерфейса пользователя (например, графическими окнами). Поэтому на данном этапе отображение описания товара и его цены не рассматривается. Пока достаточно лишь знать, что эти данные известны.
Создание экземпляров SalesLineItem
Среди постусловий в описании системной операции enterItemсодержатся Данные о создании экземпляра объекта SalesLineItem, его инициализации и связи с другими объектами. Анализируя модель предметной области, приходимrвыводу, что объектSaleсодержит объекты SalesLineItem, в связи с чем именно этому классу логично поручить создание экземпляров SalesLineItem.
В таком случае со временем объект Saleбудет связан с новым экземпляром коллекции продаваемых товаров. Из постусловий следует, что при создании экземпляра SalesLineItem необходимо указывать количество единиц покупаемого товара, поэтому данное значение необходимо передавать из объектаRegisterобъектуSale, который, в свою очередь, передаст его в качестве параметра сообщенияcreate(например, на языкеJavaэто можно реализовать с помощью вызова конструктора с параметром).
Таким образом, согласно шаблону Creator, для создания объектаSalesLineItemобъектуSaleпередается сообщениеmakeLineItem. ОбъектSaleсоздает экземпляр SalesLineItem, а затем хранит этот новый экземпляр в своем постоянном контейнере.
Параметрами сообщения makeLineItemявляются количество единиц товараquantityи спецификация товараProductSpecification, соответствующая коду товараitemID.
Нахождение ProductSpecification
Экземпляр SalesLineItemнеобходимо связать со спецификациейProductSpecification, соответствующей коду данного товараitemID. Это означает, что необходимо уметь по коду товара находить значениеProductSpecification.
Прежде чем определять, какследует находить значениеProductSpecification, необходимо решить,ктоэто будет делать.
Переформулируем задачу следующим образом.
Кто должен отвечать за нахождение значения ProductSpecification на основе кода товара itemID?
Эта проблема не является ни задачей создания экземпляра, ни задачей выбора контроллера для системного события. Здесь впервые предоставляется возможность использования шаблона InformationExpert.
В большинстве случаев здесь необходимо применить шаблон Expert, согласно которому эта обязанность возлагается на объект, обладающий нужной информацией.Какой класс обладает информацией о спецификациях товаров ProductSpecification?
Проанализировав модель предметной области, приходим к выводу, что класс ProductCatalogлогически содержит полную информацию о ProductSpecification. На основе структуры объектов предметной области можно разработать аналогичную организацию программных классов: программный классProductCatalogбудет содержать программные классыProductSpecification.
Следовательно, согласно шаблону Expert, классProductCatalogявляется хорошим кандидатом для реализации обязанности поиска, поскольку обладает полной информацией обо всех объектахProductSpecification.
Это можно реализовать, например, с помощью метода getSpecification.1
Обеспечение видимости класса ProductCatalog
Кто должен отправлять сообщение getSpecification классу ProductCatalog с запросом на получение значения ProductSpecification?
Разумно предположить, что экземпляры объектов RegisterиProductCatalogдолжны быть созданы в процессе реализации прецедента Запуск системы (StartUp), и между этими объектами должна устанавливаться постоянная связь. Согласно такому предположению, отправку сообщения getSpecification для классаProductCatalogможно поручить классуRegister.
Здесь возникает еще один важный вопрос объектно-ориентированного проектирования: вопрос видимости. Видимость(visibility) – это способность одного объекта "видеть" другой объект или ссылаться на него. Для того чтобы один объект мог отправлять сообщения другому объекту, объект-получатель должен находиться в области видимости объекта-отправителя.
Поскольку мы предположили, что объект Registerимеет постоянную связь с объектомProductCatalog(или ссылку на него), он может отправлять ему сообщения, в том числе сообщение getSpecification.
Получение значения prodactSpecification из базы данных
Очень нежелательно, чтобы в последней версии POS-системы ТТ все значения ProductSpecificationхранились в оперативной памяти. Скорее всего, они будут храниться в реляционной или объектной базе данных, и извлекаться из нее по требованию. Однако пока мы не будем рассматривать вопросы извлечения информации из базы данных, а предположим, что все значенияProductSpecificationнаходятся в оперативной памяти.
Диаграмма взаимодействия для системной операции enterItem
Согласно приведенным выше рассуждениям, можно построить диаграмму взаимодействия, отражающую распределение обязанностей и способы взаимодействия между объектами (рис. 3.3). Заметим, что эта диаграмма построена в результате взвешенного применения шаблонов GRASP.
Рисунок 3.3 – Диаграмма взаимодействия для системной операции enterItem
Сообщения сложным объектам
Заметим, что отправка сообщения сложному объекту в UMLинтерпретируется как передача сообщения объекту-контейнеру, а не каждому элементу набора объектов. Это особенно очевидно для таких операций, какfindиadd.
Например, из диаграммы взаимодействия для системной операцииenterItemможно узнать следующее:
Сообщение find, передаваемое сложному объектуProductSpecification, – это сообщение, которое отправляется один раз целому набору данных, представленному в виде сложного объекта (такому, какMapвJava).
Независимое от языка общее сообщение findв процессе программирования будет трансформировано в реальное название метода конкретной библиотеки или языка программирования. Возможно, на языкеJavaоно превратится в методMap.get. На диаграмме также можно было использовать сообщениеget. Однако мы выбрали имяfind, чтобы продемонстрировать необходимость перехода от проектных решений к конкретным библиотекам и языкам программирования.
Сообщение addпередается сложному объектуSalesLineItemдля добавления элемента в контейнер, представленный сложным объектом (таким какListвJava).