Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Реализация

Читайте также:
  1. IV.Реализация продукции
  2. RAIDS Практическая реализация
  3. Вымирание - как реализация идеала
  4. Глава 9. РЕАЛИЗАЦИЯ ИМУЩЕСТВА ДОЛЖНИКА НА ТОРГАХ
  5. Злоупотребление правом, реализация интереса и правореализация: проблемы соотношения.
  6. Интерфейс и реализация
  7. Конкретная ситуация 3 Реализация стратегических изменений
  8. Наиболее эффективная реализация божественной сути человека происходит в отношениях с людьми, в построении уважительных, любящих, дружеских отношений со всеми окружающими.
  9. Правомерное поведение, реализация права.
  10. Разработка и реализация маркетинговых проектов и программ

Прототип особенно полезен в статически типизированных языках вроде C++, где классы не являются объектами, а во время выполнения информации о типе достаточно или нет вовсе. Меньший интерес данный паттерн представляет для "аких языков, как Smalltalk или Objective С, в которых и так уже есть нечто экви­валентное прототипу (именно - объект-класс) для создания экземпляров каждо-::» класса. В языки, основанные на прототипах, например Self [US87], где созда­ние любого объекта выполняется путем клонирования прототипа, этот паттерн просто встроен.

Рассмотрим основные вопросы, возникающие при реализации прототипов:

а использование диспетчера прототипов. Если число прототипов в системе не фиксировано (то есть они могут создаваться и уничтожаться динамически), ведите реестр доступных прототипов. Клиенты должны не управлять про­тотипами самостоятельно, а сохранять и извлекать их из реестра. Клиент запрашивает прототип из реестра перед его клонированием. Такой реестр мы будем называть диспетчером прототипов.

Диспетчер прототипов - это ассоциативное хранилище, которое возвраща­ет прототип, соответствующий заданному ключу. В нем есть операции для регистрации прототипа с указанным ключом и отмены регистрации. Кли­енты могут изменять и даже «просматривать» реестр во время выполнения, а значит, расширять систему и вести контроль над ее состоянием без напи­сания кода;

а реализация операции Clone. Самая трудная часть паттерна прототип - пра­вильная реализация операции Clone. Особенно сложно это в случае, когда в структуре объекта есть круговые ссылки.

В большинстве языков имеется некоторая поддержка для клонирования объектов. Например, Smalltalk предоставляет реализацию копирования, ко­торую все подклассы наследуют от класса Object. В C++ есть копирую­щий конструктор. Но эти средства не решают проблему «глубокого и по­верхностного копирования» [GR83]. Суть ее в следующем: должны ли при


 

Порождающие паттерны

клонировании объекта клонироваться также и его переменные экземпляра или клон просто разделяет с оригиналом эти переменные? Поверхностное копирование просто, и часто его бывает достаточно. Имен­но такую возможность и предоставляет по умолчанию Smalltalk. В C++ ко­пирующий конструктор по умолчанию выполняет почленное копирование,

. то есть указатели разделяются копией и оригиналом. Но для клонирования прототипов со сложной структурой обычно необходимо глубокое копиро­вание, поскольку клон должен быть независим от оригинала. Поэтому нуж­но гарантировать, что компоненты клона являются клонами компонентов прототипа. При клонировании вам приходится решать, что именно может разделяться и может ли вообще.

Если объекты в системе предоставляют операции Save (сохранить) и Load (загрузить), то разрешается воспользоваться ими для реализации операции Clone по умолчанию, просто сохранив и сразу же загрузив объект. Опера­ция Save сохраняет объект в буфере памяти, a Load создает дубликат, ре­конструируя объект из буфера;

а инициализация клонов. Хотя некоторым клиентам вполне достаточно клона как такового, другим нужно инициализировать его внутреннее состояние полностью или частично. Обычно передать начальные значения операции Clone невозможно, поскольку их число различно для разных классов про­тотипов. Для некоторых прототипов нужно много параметров инициализа­ции, другие вообще ничего не требуют. Передача Clone параметров мешает построению единообразного интерфейса клонирования. Может оказаться, что в ваших классах прототипов уже определяются опе­рации для установки и очистки некоторых важных элементов состояния. Если так, то этими операциями можно воспользоваться сразу после клони­рования. В противном случае, возможно, понадобится ввести операцию Initialize (см. раздел «Пример кода»), которая принимает начальные значения в качестве аргументов и соответственно устанавливает внутрен­нее состояние клона. Будьте осторожны, если операция Clone реализует глубокое копирование: копии может понадобиться удалять (явно или внут­ри Initialize) перед повторной инициализацией.

Пример кода

Мы определим подкласс MazePrototypeFactory класса MazeFactory.

Этот подкласс будет инициализироваться прототипами объектов, которые ему предстоит создавать, поэтому нам не придется порождать подклассы только ради изменения классов создаваемых стен или комнат.

MazePrototypeFactory дополняет интерфейс MazeFactory конструкто­ром, принимающим в качестве аргументов прототипы:

class MazePrototypeFactory: public MazeFactory { public:

MazePrototypeFactory(Maze*, Wall*, Room*, Door*);

virtual Maze* MakeMaze() const; virtual Room* MakeRoom(int) const;




Дата добавления: 2015-09-11; просмотров: 68 | Поможем написать вашу работу | Нарушение авторских прав

Порождающие паттерны | Паттерн Builder | Пример кода | Паттерн Builder | Назначение | Порождающие паттерны | Паттерн Factory Method | Порождающие паттерны | Паттерн Prototype | Порождающие паттерны |


lektsii.net - Лекции.Нет - 2014-2025 год. (0.01 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав