What's the name of this design pattern?

2019-04-13 04:58发布

Let's suppose I need to save a text in my application into a file, but allowing the user to have more than one format (.pdf, .word, .txt, ...) to select.

A first approach could be:

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

but I usually encapsulate the above like this:

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("...");
  }
}

Using it, if I need to add a new extension/format, all I have to do is create a new class (that inherits from Writer) for that writer and implement the CanWriteTo(..) and Write(..) methods, and add that new writer to the list of writers in WritersHandler (maybe adding a method Add(Writer w) or manually, but that's not the point now).

I also use this in other situations.

My question is:

What's the name of this pattern? (maybe it's a modification of a pattern, don't know).

2条回答
冷血范
2楼-- · 2019-04-13 05:23

It's the Chain Of Responsibility.
It basically defines a chain of processing objects, where the supplied command is passed to the next processing object if the current one can't handle it.

查看更多
Juvenile、少年°
3楼-- · 2019-04-13 05:27

I would do it a bit differently than you.

The main difference would be the way of storing handlers and picking the right one. In fact I think that chain of responsibility is a bad choice here. Moreover iterating through the ist of handlers may be time consuming (if there are more of them). Dictionary provides O(1) writer retrieval. If I were to guess I'd tell that my pattern is called Strategy.

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);
  }
}
查看更多
登录 后发表回答