For a project I’m working on, I need to create objects using different source data formats, more or less like this:
public class FooService
{
protected DataFormat Format { get; set; }
public FooService(DataFormat format = DataFormat.Json)
{
Format = format;
}
public Foo GetFoo(int id)
{
string content = GetContentInFormat("someuri/foo/" + id, Format);
// Something here must create a "Foo" object
// based on Format, which could be Json, Xml or other
}
}
public enum DataFormat
{
Json,
Xml
}
I know I could:
1) Have different methods and choose the right one based on Format:
switch (Format)
{
case DataFormat.Xml:
return CreateFooFromXml(content);
case DataFormat.Json:
return CreateFooFromJson(content);
default:
throw new Exception("Invalid format.");
}
Cons: there will be at least 8 different types that will be created this way, so I need something more extensible and maintainable.
2) Make FooService an interface or abstract class and implement concrete classes, one for each format.
Cons: business logic in all classes will always be the same, except for the class instantiation. It may be confusing having JsonFooService and XmlFooService.
I would like to know what’s the best solution for this from an extensibility and maintainability point of view.
You’re clearly talking creational patterns here, but I don’t think we know enough about the complexity of the Foo’s to clearly recommend one over another. Luckily there aren’t that many of the GoF creational patterns, so you can read up on all of them in fairly short order. It appears you already understand the factory-method pattern, so you might skip to abstract factory and builder to see whether they fit the bill better.
Tips from the builder wiki:
Hope that helps.