views:

194

answers:

2

I have two data structure classes (this is a simplified version of my code)

  • Animal: Has one property “int Age”
  • Person: Has one property “DateTime Birthday”

What I am trying to accomplish is to compile “Uploading” (persisting to database), which is common across all different data structure classes. So mainly my goal is to have a small Upload method that looks like

   foreach (TypeName typeName in Enum.GetValues(typeof(TypeName)))
   {
      IDataPopulator populator = 
            new DataFactory().CreateDataPopulator(typeName);
         populator.Populate(string.Empty);
   }

But the problem is that, populator returns an object instances of different types, which I am having trying to encapsulate since they have no common properties. (IDataPopulator.TResult Populate(string data) in the code below)

Is there a way to get around this? Or does Strategy pattern not fit for this kind of scenario?

Here is the code I’ve been working with

public class Program
{
    public static void Main()
    {
        foreach (TypeName typeName in Enum.GetValues(typeof(TypeName)))
        {
            IDataPopulator populator = new DataFactory().CreateDataPopulator(typeName);
            populator.Populate(string.Empty);
        }
    }
}

public enum TypeName { Person, Animal }
public class Person { public DateTime Birthday { get; set; } }
public class Animal { public int Age { get; set; } }

public interface IDataPopulator
{
    TResult Populate(string data);
}

class AnimalDataPopulator : IDataPopulator
{
    public Animal Populate(string data)
    {
        // create an instance of Animal using data
    }
}

class PersonDataPopulator : IDataPopulator
{
    public Person Populate(string data)
    {
        // create an instance of Person using data
    }
}

public class DataFactory
{
    public IDataPopulator CreateDataPopulator(TypeName typeName)
    {
        switch (typeName)
        {
            case TypeName.Person:
                return new PersonDataPopulator();
            case TypeName.Animal:
                return new AnimalDataPopulator();
            default:
                throw new ArgumentOutOfRangeException("typeName");
        }
    }
}

public class UploadContext
{
    private readonly IUploader _Uploader;
    public UploadContext(IUploader uploader) { _Uploader = uploader; }
    public void Upload() { _Uploader.Upload(); }
}

public interface IUploader
{
    void Upload();
}

class PersonUploader : IUploader
{
    private Person _Person;
    public PersonUploader(Person person) { _Person = person; }
    public void Upload()
    {
        Console.WriteLine("Uploading person...");
    }
}
class AnimalUploader : IUploader
{
    private Animal _Animal;
    public AnimalUploader(Animal animal) { _Animal = animal; }
    public void Upload()
    {
        Console.WriteLine("Uploading animal...");
    }
}
+1  A: 

I think what you are after is either serialization, if you are just storing blobs, or an ORM framework.

Matt Howells
@Matt Howells: I am not able to understand your answer, there. A type of answer I was looking for was whether the design approach I took was right or not. I am not actually worrying about actual implementation of how to persist data to database.
Sung Meister
The whole uploader/populator thing (bizarre mix of metaphors there). It seems like what you might want to do is serialize and deserialize your objects. Either that or map them to database tables, in which case I suggest using an ORM (object-relational mapping) framework.
Matt Howells
Yes, you are right. I am trying to de/serialize objects. Maybe I was not able to understand your point initially since I have not been exposed to ORM, yet.
Sung Meister
+1  A: 

I don't see how the Strategy pattern would fit here. The pattern is about a family of algorithms, e.g. line breaking strategies. You don't have strategies here, you have a single abstract method

TResult Populate(string data);

and several implementations of it.

I also don't understand the initial problem, maybe you want to queue several serialization operations? In that case the Command pattern is your friend.

@kineas: Command pattern does look like what I am trying to do here instead of strategy pattern. Let me put that idea into action.
Sung Meister
Command pattern worked for me.
Sung Meister