Схема одноразового посетителя - Single-serving visitor pattern

В компьютерное программирование, то шаблон одноразового посетителя это шаблон дизайна. Его цель - оптимизировать реализацию посетитель который выделяется, используется только один раз, а затем удаляется (что характерно для большинства посетителей).

Применимость

Шаблон одноразового посетителя следует использовать, когда посетителям не нужно оставаться в памяти. Это часто бывает при посещении иерархии объектов (например, когда шаблон посетителя используется вместе с составной узор ), чтобы выполнить с ним одну задачу, например подсчитать количество камер в 3D-сцене.

Регулярный шаблон посетителя следует использовать, когда посетитель должен оставаться в памяти. Это происходит, когда посетитель настроен с рядом параметров, которые должны храниться в памяти для последующего использования посетителем (например, для сохранения параметров визуализации средства визуализации 3D-сцены).

Однако, если во всей программе должен быть только один экземпляр такого посетителя, может быть хорошей идеей реализовать его как одноразового посетителя и как одиночка. При этом обеспечивается возможность вызова одноразового посетителя позже с неизмененными параметрами (в данном конкретном случае «одноразовый посетитель» - это злоупотребление языком, поскольку посетитель может использоваться несколько раз).

Примеры использования

Одноразовый посетитель вызывается через промежуточные статические методы.

  • Без параметров:
     Элемент* элем; SingleServingVisitor::apply_to(элем);
  • С параметрами:
     Элемент* элем; ТИП param1, param2; SingleServingVisitor::apply_to(элем, param1, param2);
  • Реализация как синглтон:
     Элемент* элем; ТИП param1, param2; SingleServingVisitor::set_param1(param1); SingleServingVisitor::set_param2(param2); SingleServingVisitor::apply_to(элем);

Последствия

Плюсы

  • Никаких "зомби" объектов. При одноразовом посетителе гарантируется, что посетители распределяются по мере необходимости и уничтожаются, когда они становятся бесполезными.
  • Более простой интерфейс, чем посетитель. Посетитель создается, используется и предоставляется бесплатно по единственному требованию apply_to статический метод.

Минусы

  • Повторное размещение. При каждом звонке apply_to , то создается однократный посетитель, который затем отбрасывается, что отнимает много времени. Напротив, синглтон выполняет только одно выделение.

Реализация (на C ++)

Базовая реализация (без параметров)

// Объявлениекласс Элемент;класс ElementA;класс ЭлементB;класс SingleServingVisitor;... // То же, что и [[шаблон посетителя]].// Определениекласс SingleServingVisitor {защищенный:    SingleServingVisitor();общественный:    ~SingleServingVisitor();    статический пустота apply_to(Элемент*);    виртуальный пустота visit_ElementA(ElementA*) = 0;    виртуальный пустота visit_ElementB(ЭлементB*) = 0;}// Реализацияпустота SingleServingVisitor::apply_to(Элемент* элем) {    SingleServingVisitor ssv;    элем.принять(ssv);}

Передача параметров

Если необходимо инициализировать одноразового посетителя, параметры необходимо передать через статический метод:

пустота SingleServingVisitor::apply_to(Элемент* элем, ТИП param1, ТИП param2, ...) {    SingleServingVisitor ssv(param1, param2, ...);    элем.принять(&ssv);}

Реализация как синглтон

Эта реализация обеспечивает:

  • что существует не более одного экземпляра одноразового посетителя
  • что посетитель может быть доступен позже
// Определениекласс SingleServingVisitor {защищенный:    статический SingleServingVisitor* пример_;    ТИП param1_;    ТИП param2_;    SingleServingVisitor();    статический SingleServingVisitor* get_instance();    // Примечание: метод get_instance не обязательно должен быть публичнымобщественный:    ~SingleServingVisitor();    статический пустота apply_to(Элемент*);    // статические методы доступа к параметрам    статический пустота set_param1(ТИП);    статический пустота set_param2(ТИП);    виртуальный пустота visit_ElementA(ElementA*) = 0;    виртуальный пустота visit_ElementB(ЭлементB*) = 0;}// РеализацияSingleServingVisitor* SingleServingVisitor::пример_ = ЗНАЧЕНИЕ NULL;SingleServingVisitor* SingleServingVisitor::get_instance() {    если (этот->пример_ == ЗНАЧЕНИЕ NULL)        этот->пример_ = новый SingleServingVisitor();    вернуть этот->пример_;}пустота SingleServingVisitor::apply_to(Элемент* элем) {    элем->принять(get_instance());}пустота SingleServingVisitor::set_param1(ТИП param1) {    getInstance()->param1_ = param1;}пустота SingleServingVisitor::set_param2(ТИП param2) {    getInstance()->param2_ = param2;}

Связанные шаблоны