А.М. Вендров - Объектно-ориентированный анализ и проектирование (1158627), страница 21
Текст из файла (страница 21)
Информация, подлежащая сохранению, "известна" объектуCourse, а значит, согласно образцу Information Expert, на класс Courseследует возложить обязанность по сохранению. Логическим следствиемтакого рассуждения является вывод о том, что каждый объект долженотвечать за сохранение себя в базе данных. Однако при этом возникаетпроблема перегруженности класса лишними обязанностями, посколькукласс Course должен содержать методы обращения к базе данных, т.е.должен быть связан с вызовом операторов языка SQL или сервисов JDBC(Java Database Connectivity). Тогда этот класс не будет относиться кпредметной области и моделировать учебные курсы.
Кроме того,подобные действия будут дублироваться во многих других классах,информация которых подлежит постоянному хранению.Все эти проблемы приводят к нарушению основного архитектурногопринципа проектирования с разделением основных функций системы науровни, отраженного в образце "Уровни". Разнородные функции недолжны реализовываться в одном и том же компоненте. С этой точкизрения класс Course не должен отвечать за сохранение информации в базеданных.Основное достоинство образца Information Expert - поддержкаинкапсуляции.
Для выполнения требуемых задач объекты используютсобственные данные. Необходимое поведение системы обеспечиваетсянесколькими классами, содержащими требуемую информацию. Этоприводит к определениям классов, которые гораздо проще понимать иподдерживать.Образец "Creator"Проблема:Нужно определить, кто должен отвечать за создание новогоэкземпляра некоторого класса. Создание новых объектов в объектноориентированной системе является одним из стандартных видовдеятельности. Следовательно, при назначении обязанностей, связанных ссозданием объектов, полезно руководствоваться некоторым основнымпринципом.Решение:Следует назначить классу В обязанность создавать экземпляры классаА, если выполняется одно из следующих условий:119• класс В агрегирует, содержит или активно использует объектыкласса А;• класс В обладает данными инициализации, которые будутпередаваться объектам класса А при их создании (т.е.
класс Вявляется информационным экспертом).Класс В при этом определяется как создатель (creator) объектов классаА.Если несколько классов удовлетворяют этим условиям, топредпочтительнее использовать в качестве создателя класс, агрегирующийили содержащий класс А.Пример:При выполнении подчиненного потока событий "Создать график"варианта использования "Зарегистрироваться на курсы" (рис. 3.5)необходимо решить, кто должен отвечать за создание нового графика всистеме. На рис.
3.10 показаны два возможных варианта решения этойзадачи.В диаграмме на рис. 3.5 выбран вариант 1. Однако, согласно образцу"Creator", наилучшим решением является вариант 2 (новый объект классаSchedule создается классом Student, а не RegistrationController, посколькуименно Student удовлетворяет первому из перечисленных выше условий).Следствия:Образец "Creator" определяет способ распределения обязанностей,связанный с процессом создания объектов. В объектно-ориентированныхсистемах эта задача является одной из наиболее распространенных.Основным назначением образца Creator является выявление объектасоздателя, который при возникновении любого события должен бытьсвязан со всеми созданными им объектами. При таком подходеобеспечивается низкая степень связанности объектов.В некоторых случаях в качестве создателя выбирается класс, которыйсодержит данные инициализации, передаваемые объекту во время егосоздания.
На самом деле это пример использования образца InformationExpert. В процессе создания инициализирующие данные передаются спомощью метода инициализации некоторого вида, такого как конструкторязыка программирования.В некоторых сложных случаях вместо данного образцапредпочтительнее использовать известный образец Factory (Фабрика) [5] иделегировать обязанность создания объектов вспомогательному классу.120Рис.
3.10. Два варианта создания графикаОбразец "Low Coupling"Проблема:Нужно распределить обязанности между классами таким образом,чтобы снизить взаимноевлияние изменений в них и повыситьвозможность повторного использования.Решение:Следует распределить обязанности таким образом, чтобы обеспечитьслабую связанность. Связанность (coupling) - это мера, определяющаянасколько жестко один элемент связан с другими элементами, или какимколичеством данных о других элементах он обладает.
Элемент со слабойсвязанностью зависит от небольшого числа других элементов. Класс с121сильной связанностью зависит множества других классов. Наличие такихклассов нежелательно, поскольку оно приводит к возникновениюследующих проблем:• Изменения в связанных классах приводят к локальным изменениямв данном классе.• Затрудняется понимание каждого класса в отдельности.• Усложняется повторное использование, поскольку для этоготребуется дополнительный анализ классов, с которыми связанданный класс.Пример:Рассмотрим подчиненный поток событий "Создать график" вариантаиспользования "Зарегистрироваться на курсы" (рис. 3.5).
На даннойдиаграмме при создании нового графика в системе выбран вариант 1 (рис.3.10). Однако, согласно образцу "Low Coupling", наилучшим решениемявляется вариант 2, поскольку при этом у класса RegistrationControllerбудет на одну связь меньше (т.е., будет обеспечена более слабаясвязанность).СледствияОбразец Low Coupling поддерживает независимость классов, что, всвою очередь, повышает возможности повторного использования иобеспечивает более высокую эффективность приложения. Его нельзярассматривать изолированно от других образцов, таких как InformationExpert и High Cohesion.
Он также обеспечивает выполнение одного изосновных принципов проектирования, применяемых при распределенииобязанностей.Не существует абсолютной меры для определения слишком сильнойсвязанности. Важно лишь понимать связанность объектов и не упуститьтот момент, когда дальнейшее повышение связанности может привести квозникновению проблем. В целом, следует руководствоваться такимпринципом: классы, которые являются достаточно общими по своейприроде и с высокой вероятностью будут повторно использоваться вдальнейшем, должны иметь минимальную связанность с другимиклассами.Крайним случаем при реализации образца Low Coupling являетсяполное отсутствие связывания между классами. Такая ситуация тоженежелательна, поскольку основная идея объектного подхода выражается всистеме связанных объектов, которые "общаются" между собойпосредством передачи сообщений.
При слишком частом использованиипринципа слабого связывания система будет состоять из несколькихизолированныхсложныхактивныхобъектов,самостоятельновыполняющих все операции, и множества пассивных объектов, основнаяфункция которых сводится к хранению данных. Поэтому при созданииобъектно-ориентированной системы должна присутствовать некоторая122оптимальная степень связывания между объектами, позволяющаявыполнять основные функции посредством взаимодействия этих объектов.Не следует применять данный образец, когда создаются связи сустойчивыми элементами.
Сильная связанность с такими элементами непредставляет проблемы. Например, приложение Java 2 Enterprise Editionможно жестко связать с библиотеками Java, поскольку они достаточностабильны.Сильная связанность сама по себе не является проблемой. Проблемойявляется жесткое связывание с неустойчивыми элементами. Важнопонимать, что без убедительной мотивации не следует во что бы то нистало бороться за уменьшение связанности объектов.Образец "High Cohesion"Проблема:Нужно распределить обязанности между классами таким образом,чтобы каждый класс не выполнял много разнородных функций илинесвязанных между собой обязанностей.
Такие классы создаватьнежелательно, поскольку они приводят к возникновению таких жепроблем, как у классов с сильной связанностью.Решение:Следует распределить обязанности таким образом, чтобы обеспечитьсильноесцепление.Втерминахобъектно-ориентированногопроектирования сцепление (cohesion) - это мера связанности инепротиворечивости обязанностей класса. Считается, что элемент обладаетсильным сцеплением, если его обязанности тесно связаны между собой, ион не выполняет излишнего объема работы. В роли таких элементов могутвыступать классы, подсистемы, модули и т.д.Классы со слабым сцеплением, как правило, выполняют обязанности,которые можно легко распределить между другими классами.Пример:Используем тот же пример, что и для предыдущего образца (рис.3.10). Согласно образцу "High Cohesion", наилучшим решением такжеявляется вариант 2, поскольку при этом класс RegistrationControllerделегирует обязанность создания нового объекта класса Shedule классуStudent, и у самого класса RegistrationController будет на одну обязанностьменьше (т.е., его сцепление будет сильнее).Следствия:Как правило, класс с сильным сцеплением содержит сравнительнонебольшое число методов, которые функционально тесно связаны междусобой, и не выполняет слишком много функций.