title: Strategy Pattern or Interface?
body: <p>I'm looking to abstract a helper method. The method needs to be able to take in an object, do things with it depending on the type of object, and return a value. Would it be better to do something like this:</p>
  
  <pre><code>interface ICanDo
  {
   string DoSomething();
  }
  
  string DoThings(ICanDo mything)
  {
   return mything.DoSomething();
  }
  </code></pre>
  
  <p>Or is it better to do something like this:</p>
  
  <pre><code>interface IStrategy
  {
   string DoSomething(object o);
  }
  
  string DoThings(object mything, IStrategy strategy)
  {
   return strategy.DoSomething(mything);
  }
  </code></pre>
  
  <p>Is the latter even using a strategy pattern, since the strategy isn't being built into the class?</p>
  
  <p>Is there a better way to do this I'm not thinking of? Would it be better to build the strategy into the class, using a wrapper for any class that needs to have DoThings run on it?</p>
  
  <p>Sorry--I'm new to this pattern and trying to figure out where and how to use it best.</p>
  
  <p>This is what I ended up putting together. I'm unsure if this follows good development principles.</p>
  
  <pre><code>class IndexWrapper
  {
      public interface IDocumentable
      {
          Document BuildDocument();
      }
  
      public interface IDocumentBuilder
      {
          Type SupportedType { get; }
  
          Document BuildDocument(object o);
      }
  
      public class StringDocumentBuilder : IDocumentBuilder
      {
          public Type SupportedType { get { return typeof(string); } }
  
          public Document BuildDocument(object o)
          {
              Document doc = new Document();
              doc.Add(new Field("string", o as string, Field.Store.YES, Field.Index.ANALYZED));
              return doc;
          }
      }
  
      public static class IndexableFactory
      {
          public static IDocumentable GetIndexableObject(object o)
          {
              return GetIndexableObject(o, DocumentBuilderFactory.GetBuilder(o));
          }
  
          public static IDocumentable GetIndexableObject(object o, IDocumentBuilder builder)
          {
              return new IndexableObject(o, builder);
          }
      }
  
      public static class DocumentBuilderFactory
      {
          private static List&lt;IDocumentBuilder&gt; _builders = new List&lt;IDocumentBuilder&gt;();
  
          public static IDocumentBuilder GetBuilder(object o)
          {
              if (_builders.Count == 0)
              {
                  _builders = Assembly.GetExecutingAssembly()
                                     .GetTypes()
                                     .Where(type =&gt; typeof(IDocumentBuilder).IsAssignableFrom(type) &amp;&amp; type.IsClass)
                                     .Select(type =&gt; Activator.CreateInstance(type))
                                     .Cast&lt;IDocumentBuilder&gt;()
                                     .ToList();
              }
  
              return _builders.Where(builder =&gt; builder.SupportedType.IsAssignableFrom(o.GetType())).FirstOrDefault();
          }
      }
  
      private class IndexableObject : IDocumentable
      {
          object _o;
          IDocumentBuilder _builder;
  
          public IndexableObject(object o) : this(o, DocumentBuilderFactory.GetBuilder(o)) { }
          public IndexableObject(object o, IDocumentBuilder builder)
          {
              _o = o;
              _builder = builder;
          }
  
          virtual public Document BuildDocument()
          {
              return _builder.BuildDocument(_o);
          }
      }
  }
  </code></pre>