September 21

Шаблонный метод

Поведенченский паттерн.

Определяет скелет алгоритма, позволяющий изменять определенные шаги.

Определяется абстрактный класс, в нём определяется метод, который вызывает последовательность других виртуальны или абстрактных методов методов.

Определяется класс наследник (concrete) от абстрактного, который переопределяет некоторые шаги.

Например, классы, который выкачивает данные, обрабатывает и сохраняет.

public abstract class DataProcessor
{
     public void Process()
     {
         DownloadDAta();
         ParseData();
         SaveData();
         
         if (ShouldSendNotification())
         {
            SendNotification();
         }
     }
     
     //обязательные шаги
     protected abstract void DownloadData();
     protected abstract void ParseData();
     
     //шаг с дефолтной реализацией
     protected virtual void SaveData()
     {
     }
     
     //Хук
     protected virtual bool ShouldSendNotification() => true;
     
     //неопределяемый
     private void SendNotification()
     {
     }
}

Классы-реализации:

public class JsonDataProcessor : DataProcessor
{
      protected override void DownloadData()
      {
          //загрузка из json
      }
      
      protected override void ParseData()
      {
          //парсинг json
      }
}

Использование

DataProcessor processor = new JsonDataProcessor()
processor.Process();

Паттерн используют для создания библиотек, позволяющей пользователю определять какие-то шаги.

Примеры из стандартных библиотек .NET:

BackgroundService - класс для создания долгосрочных задач.
Определяет метод StartAsync с дефолтной реализацией, также определяет чистый виртуальный метод ExecuteAsync, который надо переопределить.

IO.Stream - базовый класс для всех потоков. В нём методы WriteAsync, ReadAsync и т.д. содержат базовую логику проверки параметров, создания асинхронных контекстов и вызова внутренних абстрактных виртуальных методов, которые должны перопределиться в конкретных реализациях FileStream, NetworkStream, MemoryStream и т.д.