Я читаю о шаблоне прототипа по книге GoF. Вот текстовый фрагмент
Динамическое конфигурирование приложения с классами: немного времени выполнения
среды позволяют загружать классы в приложение динамически.
образец прототипа является ключом к эксплуатации таких объектов в
язык как C ++.Приложение, которое хочет создавать экземпляры динамически загружаемого
классы не смогут ссылаться на его конструктор статически.
Вместо этого среда выполнения создает экземпляр каждого класса
автоматически при загрузке и регистрации с прототипом
менеджер. Затем приложение может запросить у менеджера прототипа новый
загруженные классы, классы, которые не были добавлены в программу изначально
Мои вопросы по выше
Что автор имеет в виду под «приложением, которое хочет создавать экземпляры динамически загружаемых классов, не сможет ссылаться на свой конструктор статически»? Например, если мы используем динамическую библиотеку ссылок, я все еще могу создать объект, используя new, так что автор имеет в виду, что мы не сможем ссылаться на конструктор статически?
Просьба привести пример того, как шаблон прототипа используется для динамического использования классов загрузки приложения.
Мои 50 центов на это:
Пример (я напишу один из макушки головы, чтобы подчеркнуть сценарий, в котором он был бы полезен, тогда я напишу другой, в который я на самом деле натолкнулся)
Имея динамическую библиотеку TextEditorWidgets.dll и ваше основное приложение, TextEditorWidget предоставляет абстрактный прототип TEWPrototype и фабричный метод получения определенных прототипов в соответствии, скажем, с строковым идентификатором.
Фабричный метод выставляется из dll, определенного как:
TEWPrototype* TEWPrototype::getPrototypeFor(string identifier)
{
TEWPrototype* result;
if (identifier == "SomeWidget")
{
result = ConcreteSomeWidgetPrototype;
} else if ...
return result;
}
Внутри вашего приложения вы можете использовать следующий код:
{
vector<TEWPrototype*> allocatedWidgets;
...
TEWPrototype* SomeWidget = TEWPrototype::getPrototypeFor("SomeWidget").clone();// you are now the memory owner
allocatedWidgets.push_back(SomeWidget); // keep for deletion
TextEditorWidgetsHandle->doSomethingWithTheWidget(SomeWidget);// pass the instantiation to the consumer who knows the widget full definition
}
В приведенном выше примере у вас есть следующие плюсы в качестве разработчика приложения:
Плюсы как разработчик dll:
Практический пример:
Во время работы над игрой команда разработчиков создавала новые объекты, и нам нужен был быстрый способ дать дизайнерам новые объекты, которые они могли бы добавить на игровую сцену. У нас был свой собственный редактор, поэтому мы могли контролировать инструмент дизайна.
Подход состоял в том, чтобы World Editor загружал .dll, а затем выставлял в меню редактора, какие объекты были загружены в dll. Редактор не знал, какие классы были внутри dll, он знал только о том, что у них есть функция draw и setPosition (и некоторые другие вещи).
Когда dll была загружена, внутри редактора имя объекта было добавлено в менеджер прототипов объекта (в основном у нас была статическая функция getAvailableObjects, и после загрузки dll мы запрашивали ее, чтобы получить строки).
Когда Дизайнер выбирал из меню объект (скажем, например, Crate), тогда был создан новый экземпляр этого объекта, который был нарисован внутри редактора, и дизайнер мог перемещать его.
Редактор не мог создать экземпляр объекта самостоятельно, потому что он ничего не знал ни о размере объекта, ни о своем конструкторе. Однако у нас были предварительно созданные объекты для каждого типа, которые клонировались каждый раз, когда Художник выбирал создание «нового» ящика.
Предварительно созданные объекты также использовались в предварительном просмотре.
Когда команда разработчиков выпустила новый набор сущностей, мы просто предоставили новую dll для дизайнеров, и им нужно было только «обновить» редактор BOOM: волшебство произошло: новые объекты в меню.
В качестве альтернативы, абстрактная фабрика может обеспечить такую же функциональность.