Как называется этот шаблон дизайна? - PullRequest
2 голосов
/ 16 февраля 2011

Предположим, мне нужно сохранить текст в моем приложении в файл, но позволить пользователю выбрать более одного формата (.pdf, .word, .txt, ...).

Первый подход может быть:

if (extension == ".pdf")
  ExportToPdf(file);
else if (extension == ".txt")
  ExportToTxt(file);
...

но я обычно инкапсулирую вышесказанное так:

abstract class Writer
{
  abstract bool CanWriteTo(string file);
  abstract void Write(string text, string file);
}

class WritersHandler
{
  List<Writer> _writers = ... //All writers here

  public void Write(string text, string file) 
  {
    foreach (var writer in _writers) 
    {
      if (writer.CanWriteTo(file) 
      {
        writer.Write(text, file);
        return;
      {
    }
    throw new Exception("...");
  }
}

Используя его, если мне нужно добавить новое расширение / формат, все, что мне нужно сделать, это создать новый класс (который наследуется от Writer) для этого устройства записи и реализовать методы CanWriteTo(..) и Write(..), и добавьте этого нового автора в список авторов в WritersHandler (возможно, добавив метод Add(Writer w) или вручную, но сейчас это не главное).

Я также использую это в других ситуациях.

Мой вопрос:

Как называется этот шаблон? (может быть, это модификация шаблона, не знаю).

Ответы [ 2 ]

5 голосов
/ 16 февраля 2011

Это Цепочка ответственности .
Она в основном определяет цепочку объектов обработки, где переданная команда передается следующему объекту обработки, если текущий не может с ним справиться.

1 голос
/ 18 февраля 2011

Я бы сделал это немного иначе, чем вы.

Основным отличием будет способ хранения обработчиков и выбор правильного.На самом деле, я считаю, что цепь ответственности - плохой выбор.Более того, перебор списка обработчиков может занять много времени (если их больше).Словарь обеспечивает O (1) поиск писателя.Если бы я догадался, я бы сказал, что мой паттерн называется «Стратегия».

abstract class Writer
{
  abstract string SupportedExtension {get;}
  abstract void Write(string text, string file);
}

class WritersHandler
{
  Dictionary<string,Writer> _writersByExtension = ... //All writers here

  public void Init(IEnumerable<Writer> writers)
  {
     foreach ( var writer in writers )
     {
        _writersByExtension.Add( writer.SupportedExtension, writer );
     }
  }

  public void Write(string text, string file) 
  {
    Writer w = _writersByExtension.TryGetValue( GetExtension(file) );
    if (w == null)
    {
       throw new Exception("...");
    }
    w.Write(text, file);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...