开发者

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开发者_JS百科 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...


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);
    }
}


You've got a couple of options, I think:

  1. Define some sort of object (such as a Dictionary) that contains the parameters that each different instance should have. The code which calls the factory method will be responsible for constructing the Dictionary correctly (you should probably make sure the keys are constants defined in each of the sub-classes) and passing it in. The constructor for each of the sub-classes will be responsible for validating the object and ensuring that everything they need is present. If it isn't, they should throw an exception providing reasonable information.

  2. If the parameters aren't directly needed for object construction, you could add them as properties. The calling code would be responsible for setting these properties, and the subclasses would need to validate the properties have been set when they need the properties. If they haven't, then again they should throw an exception providing reasonable information.

The biggest thing you're going to lose here is compile-time error checking of these parameters - if the calling code isn't providing, for instance, the word count parameter for the WordFile class, there won't be a compiler error.


It looks like you are trying to create objects of classes which have different parameters to their constructors. The Factory pattern does not help you solve that. It does help solve the fact that depending on the filename it will create an appropriate object. To pass them different parameters, you will have to do that once the objects are created.

One solution could be to have a list or array of arguments to be passed and your factory could determine the type of object to create and then use the parameter list or array to create the desired object. For example

List<int> param = new List<int>();
param.Add(200);   //So add as many parameters as you want
//The factory will simply pass those to the objects it is creating
//And then pass this pass this param to your File.Create() method
File.Create(param);

The only benefit here of using a factory here is that your code will be independent of the specific implementations of the various File Type classes that you implementing. Otherwise, I would suggest not use to use this pattern and simply create your objects directly as you already know what to create.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜