Search code examples
c#factoryencapsulation

Need some help with creating a factory class to encapsulate object creation


I have a family of classes which i feel needs some encapsulation over the creation methods. Take for example:

public abstract class File
{   
    protected File(string fileName)
    {
        Name = fileName;
    }
    string Name {get; set;}
}

public class ImageFile : File
{
    protected ImageFile(string fileName, int width, int Height) :base(fileName)
    {
        Height = height;
        Width = width;  
    }

    int Height {get; set;}
    int Width {get; set;}
}

public class WordFile : File
{
    protected WordFile(string fileName, int wordCount) :base(fileName)
    {
        WordCount = wordCount;
    }

   int WordCount {get; set;}
}

Given this class hierarchy, what is the best method for me to encapsulate the creation method of each distinct classes? It would be helpful if you can provide some examples of using a factory class?

Many Thanks

Edit

One idea i had i mind was a Factory method in the abstract class which returns the concrete class. e.g

public abstract class File
    {   
        protected File(string fileName)  
        {
         ....
        } 

        string Name {get; set;}
        public static File Create(string fileName) 
        {
            if(filename.Contains("jpg")
            {
               return new ImageFile(...);
            }
            .... 
        }
    }

But in this example im not sure how i can pass the unqiue parameters for each of the concrete types. i.e Width, Height, WordCount...


Solution

  • How about creating a different factory for each of these file types? Your File.Create(...) method can choose which one to invoke, and then each factory would be responsible for reading a particular type of file, creating the data necessary to generate the File object you want to have, and returning it.

    public static File Create(string fileName)
    {
        var factory = GetFactory(fileName);
        return factory.CreateFile(fileName);
    }
    
    public static IFileFactory GetFactory(string fileName)
    {
        if(Path.GetExtension(fileName).toUpperInvariant() == ".JPG")
        {
            return new ImageFileFactory();
        }
        //...
    }
    
    public interface IFileFactory
    {
        File CreateFile(string fileName);
    }
    public class ImageFileFactory : IFileFactory
    {
        public File CreateFile(string fileName)
        {
            int width = GetWidth(fileName);
            int height = GetHeight(fileName);
            return new ImageFile(fileName, width, height);
        }
    }