“Патерн Вівторка” #7: Шаблонний метод (Template Method)

Уявімо собі, що ми маємо розробити систему пошуку повідомлень, що слалися у нашій системі. Процес пошуку складається із декількох операцій, які є загальними для всіх повідомлень, але специфіка методів може відрязнятися для деяких типів повідомлень.
Вам слід написати клас Searcher, який буде енкапсулювати алгоритм пошуку, але  ви також хочете залишити можливість перевизначити деякі елементи алгоритму для певних методів. Як це можна легко зробити?


ШАБЛОННИЙ МЕТОД

Патерн сам по собі є досить інтуїтивним, так само як і його реалізація. Вам потрібен базовий клас, що містить основні операції і один Шаблонний Метод (Search), який буде оперувати базовими операціями. Кожна із тих операцій може бути перевантажена в похідному класі.

Я написав наївну імплементацію патерну, оскільки викликаю операції одну за одною в шаблонному методі. В реальному житті  ви можете написати складний алгоритм побудований на основі базових операції. І вам буде лишень потрібно перевантажити деякі із них, або інакше кажучи, перевантажити частини алгоритму. Також можна позначити базові операції (методи) за допомогою abstract, що буде вимагати їхньої імплементації у похідних класах.

Приклад реалізації

public class MessagesSearcher
{
protected DateTime DateSent;
protected String PersonName;
protected int ImportanceLevel;

public MessagesSearcher(DateTime dateSent, String personName, int importanceLevel)
{
DateSent = dateSent;
PersonName = personName;
ImportanceLevel = importanceLevel;
}

//базові операції (primitive operations)
protected void СreateDateCriteria()
{
Console.WriteLine("Standard date criteria has been applied.");
}
protected void СreateSentPersonCriteria()
{
Console.WriteLine("Standard person criteria has been applied.");
}
protected void СreateImportanceCriteria()
{
Console.WriteLine("Standard importance criteria has been applied.");
}

//ШАБЛОННИЙ МЕТОД
public String Search()
{
//Основне в цьому методі те, що ми тут будуємо якусь логіку пошуку,
//яка використовує примітивні операції, які можуть бути перевантажені
СreateDateCriteria();
СreateSentPersonCriteria();
Console.WriteLine("Template method does some verification accordingly to search algo.");
СreateImportanceCriteria();
Console.WriteLine("Template method verifies if message could be so important or useless from person provided in criteria.");
Console.WriteLine();
return "Some list of messages...";
}
}

public class ImportantMessagesSearcher : MessagesSearcher
{
public ImportantMessagesSearcher(DateTime dateSent, String personName)
: base(dateSent, personName, 3) // 3 означає що повідомлення важливе
{
}

//одна операція перегружена (IMPORTANT в кінці)
protected void СreateImportanceCriteria()
{
Console.WriteLine("Special importance criteria has been formed: IMPORTANT");
}
}

public class UselessMessagesSearcher : MessagesSearcher
{
public UselessMessagesSearcher(DateTime dateSent, String personName)
: base(dateSent, personName, 1) //1 означає, що меседж в пень комусь треба
{
}

//одна операція перегружена (USELESS в кінці)
protected void СreateImportanceCriteria()
{
Console.WriteLine("Special importance criteria has been formed: USELESS");
}
}

А ось використання:

MessagesSearcher searcher = new UselessMessagesSearcher(DateTime.Today, "Sally");
searcher.Search();
searcher = new ImportantMessagesSearcher(DateTime.Today, "Killer");
searcher.Search();

Вивід:

Standard date criteria has been applied.
Standard person criteria has been applied.
Template method does some verification accordingly to search algo.

Special importance criteria has been formed: USELESS

Template method verifies if message could be so important or useless from person provided in criteria.

Standard date criteria has been applied.
Standard person criteria has been applied.
Template method does some verification accordingly to search algo.

Special importance criteria has been formed: IMPORTANT

Template method verifies if message could be so important or useless from person provided in criteria.

Надіюся, що мій приклад не є важким для розуміння і не вводить в оману.

Add a Comment

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *