- •Проектирование информационных систем
- •Вопрос 1. Обязанности, методы, взаимодействия
- •Вопрос 2. Шаблоны
- •Information Expert
- •Шаблон Information Expert
- •Шаблон Creator
- •Шаблон Low Coupling
- •Шаблон High Cohesion
- •Шаблон Controller
- •Вопрос 3. Реализация прецедентов
- •Пример: Реализация прецедентов для данной итерации разработки pos системы тт
- •Проектное решение: makeNewSale
- •Выбор класса-контроллера
- •Проектное решение: enterItem
- •Проектное решение: endSale
- •Проектное решение: makePayment
- •Проектное решение: startup
- •Проектное решение: store-create
- •Подключение уровня интерфейса пользователя к уровню предметной области
Проектное решение: store-create
Задачи создания и инициализации возникают в процессе проектирования приложения, в частности, при разработке проектного решения для операции enterItem. Из рассмотренных выше диаграмм взаимодействия следует необходимость инициализации для следующих объектов.
Необходимо создать экземпляры объектов Store, Register, ProductCatalog и ProductSpecification.
Объект ProductCatalogнеобходимо связать с объектомProductSpecification.
Объект Storeнеобходимо связать с объектомProductCatalog.
Объект Storeнеобходимо связать с объектомRegister.
Объект Registerнеобходимо связать с объектомProductCatalog.
На рис. 3.12 показано соответствующее проектное решение. Для создания объектов ProductCatalogиRegister, согласно шаблонуCreator, был выбран объектStore. В процессе аналогичных рассуждений для создания объектовProductSpecificationбыл выбран объектProductCatalog. Напомним, что такой подход к созданию спецификации можно рассматривать лишь как временный. При окончательном проектировании эти объекты при необходимости будут материализовываться из базы данных.
Обозначение UML:обратите внимание, что создание всех экземпляровProductSpecificationи их добавление в контейнер обозначено символом *, следующим за порядковым номером операции.
Рисунок 3.12 – Создание исходного объекта предметной области и последующих объектов
Интересное различие между этапами анализа и проектирования состоит в том, что объект Storeсоздает лишьодинобъектRegister. В реальной жизни магазин может содержать множество терминалов POS-системы. Однако мы рассматриваем программный продукт. Поэтому согласно требованиям к системе, программный объектStoreдолжен создать единственный экземпляр программного объектаRegister.
Количество классов и объектов в моделях предметной области и проектирования может различаться.
Подключение уровня интерфейса пользователя к уровню предметной области
Как отмечалось выше, приложения делятся на логические уровни, представляющие различные аспекты функционирования приложения, в том числе уровень графического интерфейса пользователя и уровень объектов предметной области (для реализации логики предметной области).
Основные проектные решения, обеспечивающие видимость объектов уровня Предметной области для объектов уровня пользовательского интерфейса, сводятся к следующему.
Инициализирующая программа (например, метод mainJava) создает и объекты уровня пользовательского интерфейса, и объект предметной области, а затем передает этот объект на уровень интерфейса пользователя.
Объект пользовательского интерфейса получает объект предметной области из стандартного источника, например, от объекта-фабрики, отвечающего за создание объектов предметной области.
Следующий фрагмент кода демонстрирует пример использования первого подхода.
Будучи связанным с экземпляром объекта Register(выступающим в данном приложении в роли внешнего контроллера), объект уровня пользовательского интерфейса может направить ему сообщение о системном событии, такое какenterItemилиendSale(рис. 3.13).
Рисунок 3.13 – Связь уровней предметной области и пользовательского интерфейса
Для передачи сообщения enterItemнеобходимо иметь диалоговое окно, в котором будет отображаться общая стоимость каждого товара. При этом можно использовать несколько проектных решений:
Добавить объекту RegisterметодgetTotal. Тогда с уровня пользовательского интерфейса объектуRegisterбудет передаваться сообщение getTotal, а этот объект, в свою очередь, перенаправит это сообщение объектуSale. Преимуществом такого подхода является низкая степень связывания между уровнями пользовательского интерфейса и предметной области – пользовательскому интерфейсу известен лишь один объектRegister. Однако при этом "раздувается" интерфейс объектаRegister, что приводит к слабой степени зацепления этого объекта.
Интерфейс пользователя запрашивает ссылку на текущий объект Sale, а затем при необходимости вычисления общей стоимости (или для получения любой другой информации о продаже) он передает сообщение напрямую объектуSale. Такое проектное решение повышает степень связывания между уровнями пользовательского интерфейса и предметной области. Однако, как указывалось при рассмотрении шаблонаGRASPLowCoupling, высокая степень связывания сама по себе не является проблемой. Проблема возникает при связывании с неустойчивыми объектами. ОбъектSaleможно считать устойчивым, поскольку он является неотъемлемой частью проектного решения. Следовательно, связывание с этим объектом не составляет проблемы.
Как видно из рис. 3.14, в проектном решении для данного приложения выбран второй подход.
Заметим, что, согласно этим диаграммам, окно Java(ProcessSaleJFrame), составляющее часть уровня пользовательского интерфейса, не отвечает за реализацию логики приложения. Оно лишь направляет запросы для выполнения системных операций объектам уровня предметной области через объектRegister. Отсюда следует один из важных принципов проектирования.
Обязанности объектов уровней пользовательского интерфейса и предметной области: уровень пользовательского интерфейса не должен отвечать за реализацию логики приложения. Его обязанностью является лишь выполнение задач пользовательского интерфейса, например, обновление информации в диалоговых окнах.
Объекты уровня пользовательского интерфейса должны направлять запросы на выполнение всех задач предметной области на уровень объектов предметной области, который и отвечает за их выполнение.
Рисунок 3.14 – Взаимодействие уровней пользовательского интерфейса и предметной области
Задание на самостоятельную работу (для выбранной темы курсового проекта):
Уточнить диаграммы взаимодействия на основе шаблонов GRASP;
Построить диаграмму взаимодействия для системной операции startup;
Связать уровни предметной области и пользовательского интерфейса для основного успешного сценария (рис. 3.14).
1 В каждом языке приняты свои соглашения об именовании методов. В Java всегда используется форма
object.getFoo(), в C++ принято использовать обозначение object.foo(), а в С#–object.Foo.