Одноразовий відвідувач (шаблон поведінки) — Вікіпедія

Одноразовий відвідувач (англ. Single-serving visitor) — шаблон поведінки. Призначений для оптимізації роботи шаблону відвідувач (Visitor). Використовується лише один раз, після закінчення всіх операцій він видаляється(у більшості випадків).

Використання[ред. | ред. код]

Цей шаблон поведінки є особливим випадком використання паттерна «відвідувач», тому його потрібно застосовувати у певних особливих випадках, таких як:

  • В програмі має бути тільки один екземпляр такого відвідувача. В певних випадках можна реалізувати такого відвідувача, як одинака. При цьому можна бути впевненим, що відвідувач може бути викликаний пізніше без змін параметрів.
  • Він є особливим випадком реалізації паттерна «відвідувач», тож він також описує операцію, яка виконується над об'єктами інших класів, він може виконати ті ж самі функції, що і у випадку звичайного паттерну «відвідувач», але після виконання ним заданих функцій він видаляється.
  • Після виконання певної операції програми, не потрібно щоб відвідувачі залишитися в пам'яті. Це часто трапляється при відвідуванні великої кількості об'єктів, або ієрархії (наприклад, коли шаблон відвідувач використовується разом з шаблоном Компоновщик) для виконання одного завдання на ньому.
  • Шаблон регулярного відвідувача слід використовувати, коли відвідувач повинен залишитися в пам'яті. Це потрібно для того щоб встановити відвідувачем ряд налаштувань, які будуть збережені в пам'яті для пізнього використання відвідувачем.

Приклади використання[ред. | ред. код]

Паттерн одноразового відвідувача викликається через проміжні слої статичних методів

Реалізація на C++

Без параметрів:

Element* elem;       SingleServingVisitor::apply_to(elem); 

З параметрами:

Element* elem;  TYPE param1, param2;  SingleServingVisitor::apply_to(elem, param1, param2); 

Реалізація на C#

Без параметрів:

public static Element elem;        SingleServingVisitor.apply_to(elem); 

З параметрами:

public static Element elem; 	 public static TYPE param1 = new TYPE(); 	 public static TYPE param2 = new TYPE(); 	 SingleServingVisitor.apply_to(elem, param1, param2); 

Наслідки[ред. | ред. код]

Переваги[ред. | ред. код]

- Відвідувачі викликаються при необхідності і можуть знищуватися без будь-якої шкоди. Тим самим не створюючи "зомбованих об'єктів"

- Відвідувач створюється, використовується і знищується від єдиного виклику певного статичного методу який був для цього призначений.

Недоліки[ред. | ред. код]

- Є істотний недолік у тому, що одноразовий відвідувач при виклику певного методу, він спочатку створюється, а потім знищується, це непродуктивна операція, яка забирає достатньо велику кількість часу.

Передавання параметрів[ред. | ред. код]

Якщо одноразовий відвідувач був ініціалізований, то параметри повинні передаватися через статичний метод:

Реалізація на C++

void SingleServingVisitor::apply_to(Element* elem, TYPE param1, TYPE param2, ...)  {     SingleServingVisitor ssv(param1, param2, ...);     elem.accept(&ssv); } 

Реалізація на C#

public partial class SingleServingVisitor { 	public void apply_to(Element elem, TYPE param1, TYPE param2, ... ) 	{ 		SingleServingVisitor ssv = new SingleServingVisitor(param1, param2, ...); 		elem.accept(ssv); 	} } 

Використання як одинака (singleton)[ред. | ред. код]

Така реалізація забезпечує:

- Не більше одного екземпляра самообслуговуючого відвідувача

- Доступ до відвідувача може бути надано пізніше


Реалізація на C++

// Призначення class SingleServingVisitor { protected:     static SingleServingVisitor* instance_;     TYPE param1_;     TYPE param2_;     SingleServingVisitor();     static SingleServingVisitor* get_instance();     // Зауваження: метод get_instance не повинен бути публічним  public:     ~SingleServingVisitor();     static void apply_to(Element*);     //статичні методи для доступу до параметрів     static void set_param1(TYPE);     static void set_param2(TYPE);       virtual void visit_ElementA(ElementA*) = 0;     virtual void visit_ElementB(ElementB*) = 0; } // Реалізація SingleServingVisitor* SingleServingVisitor::instance_ = NULL; SingleServingVisitor* SingleServingVisitor::get_instance()  {     if (this->instance_ == NULL)         this->instance_ = new SingleServingVisitor();     return this->instance_; } void SingleServingVisitor::apply_to(Element* elem)  {     elem->accept(get_instance()); } void SingleServingVisitor::set_param1(TYPE param1)  {     getInstance()->param1_ = param1; } void SingleServingVisitor::set_param2(TYPE param2)  {     getInstance()->param2_ = param2; } 

Реалізація на C#

// Призначення public abstract class SingleServingVisitor { 	protected static SingleServingVisitor instance_ = null; 	protected TYPE param1_ = new TYPE(); 	protected TYPE param2_ = new TYPE(); 	// Реалізація  	protected static SingleServingVisitor get_instance() 	{ 		if (this.instance_ == null) 			this.instance_ = new SingleServingVisitor(); 		return this.instance_; 	}  	// Зауваження: метод get_instance не повинен бути публічним         SingleServingVisitor();  	public static void apply_to(Element elem) 	{ 		elem.accept(get_instance()); 	}  	//статичні методи для доступу до параметрів 	public static void set_param1(TYPE param1) 	{ 		getInstance().param1_ = param1; 	}  	public static void set_param2(TYPE param2) 	{ 		getInstance().param2_ = param2; 	}  	public abstract void visit_ElementA(ElementA NamelessParameter);  	public abstract void visit_ElementB(ElementB NamelessParameter); }