динамическое конфигурирование приложения с использованием шаблона прототипа

Я читаю о шаблоне прототипа по книге GoF. Вот текстовый фрагмент

Динамическое конфигурирование приложения с классами: немного времени выполнения
среды позволяют загружать классы в приложение динамически.
образец прототипа является ключом к эксплуатации таких объектов в
язык как C ++.

Приложение, которое хочет создавать экземпляры динамически загружаемого
классы не смогут ссылаться на его конструктор статически.
Вместо этого среда выполнения создает экземпляр каждого класса
автоматически при загрузке и регистрации с прототипом
менеджер. Затем приложение может запросить у менеджера прототипа новый
загруженные классы, классы, которые не были добавлены в программу изначально

Мои вопросы по выше

  1. Что автор имеет в виду под «приложением, которое хочет создавать экземпляры динамически загружаемых классов, не сможет ссылаться на свой конструктор статически»? Например, если мы используем динамическую библиотеку ссылок, я все еще могу создать объект, используя new, так что автор имеет в виду, что мы не сможем ссылаться на конструктор статически?

  2. Просьба привести пример того, как шаблон прототипа используется для динамического использования классов загрузки приложения.

3

Решение

Мои 50 центов на это:

  1. Я полагаю, что автор имеет в виду ситуации, когда у вас нет определений классов в библиотеке символов, однако вы хотите создавать экземпляры объектов и передавать их функциям потребителя библиотеки (так что вы являетесь владельцем памяти, общая библиотека — это потребитель, но у вас нет доступа к конкретным классам внутри библиотеки)
  2. Пример (я напишу один из макушки головы, чтобы подчеркнуть сценарий, в котором он был бы полезен, тогда я напишу другой, в который я на самом деле натолкнулся)

    Имея динамическую библиотеку 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 выделяет, когда и как
    • вы будете контролировать, будут ли виджеты удалены или нет в течение всего времени жизни приложения

    Плюсы как разработчик dll:

    • вы сможете добавлять новые виджеты, одновременно обеспечивая обратную функциональность
    • у вас есть гарантия, что никто не будет использовать ваши внутренние функции виджетов вне .dll

Практический пример:

Во время работы над игрой команда разработчиков создавала новые объекты, и нам нужен был быстрый способ дать дизайнерам новые объекты, которые они могли бы добавить на игровую сцену. У нас был свой собственный редактор, поэтому мы могли контролировать инструмент дизайна.

Подход состоял в том, чтобы World Editor загружал .dll, а затем выставлял в меню редактора, какие объекты были загружены в dll. Редактор не знал, какие классы были внутри dll, он знал только о том, что у них есть функция draw и setPosition (и некоторые другие вещи).

Когда dll была загружена, внутри редактора имя объекта было добавлено в менеджер прототипов объекта (в основном у нас была статическая функция getAvailableObjects, и после загрузки dll мы запрашивали ее, чтобы получить строки).

Когда Дизайнер выбирал из меню объект (скажем, например, Crate), тогда был создан новый экземпляр этого объекта, который был нарисован внутри редактора, и дизайнер мог перемещать его.

Редактор не мог создать экземпляр объекта самостоятельно, потому что он ничего не знал ни о размере объекта, ни о своем конструкторе. Однако у нас были предварительно созданные объекты для каждого типа, которые клонировались каждый раз, когда Художник выбирал создание «нового» ящика.

Предварительно созданные объекты также использовались в предварительном просмотре.

Когда команда разработчиков выпустила новый набор сущностей, мы просто предоставили новую dll для дизайнеров, и им нужно было только «обновить» редактор BOOM: волшебство произошло: новые объекты в меню.

В качестве альтернативы, абстрактная фабрика может обеспечить такую ​​же функциональность.

1

Другие решения


По вопросам рекламы [email protected]