Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm having a bit of a design dilemma here. I'm writing a library that consists of a bunch of template classes that are designed to be used as a base for creating content. For example:

public class Template
{
    public string Name {get; set;}
    public string Description {get; set;}
    public string Attribute1 {get; set;}
    public string Attribute2 {get; set;}

    public Template()
    {
        //constructor
    }

    public void DoSomething()
    {
        //does something
    }
    ...
}

The problem is, not only is the library providing the templates, it will also supply quite a few predefined templates which are instances of these template classes. The question is, where do I put these instances of the templates?

The three solutions I've come up with so far are:

1) Provide serialized instances of the templates as files.

On the one hand, this solution would keep the instances separated from the library itself, which is nice, but it would also potentially add complexity for the user. Even if we provided methods for loading/deserializing the files, they'd still have to deal with a bunch of files, and some kind of config file so the app knows where to look for those files. Plus, creating the template files would probably require a separate app, so if the user wanted to stick with the files method of storing templates, we'd have to provide some kind of app for creating the template files.

Also, this requires external dependencies for testing the templates in the user's code.

2) Add readonly instances to the template class

Example:

public class Template
{
    public string Name {get; set;}
    public string Description {get; set;}
    public string Attribute1 {get; set;}
    public string Attribute2 {get; set;}

    public Template PredefinedTemplate
    {
        get
        {
            Template templateInstance = new Template();
            templateInstance.Name = "Some Name";
            templateInstance.Description = "A description";
            ...
            return templateInstance;
        }
    }

    public Template()
    {
        //constructor
    }

    public void DoSomething()
    {
        //does something
    }
    ...
}

This method would be convenient for users, as they would be able to access the predefined templates in code directly, and would be able to unit test code that used them. The drawback here is that the predefined templates pollute the Template type namespace with a bunch of extra stuff. I suppose I could put the predefined templates in a different namespace to get around this drawback. The only other problem with this approach is that I'd have to basically duplicate all the namespaces in the library in the predefined namespace (e.g. Templates.SubTemplates and Predefined.Templates.SubTemplates) which would be a pain, and would also make refactoring more difficult.

3) Make the templates abstract classes and make the predefined templates inherit from those classes.

For example:

public abstract class Template
{
    public string Name {get; set;}
    public string Description {get; set;}
    public string Attribute1 {get; set;}
    public string Attribute2 {get; set;}

    public Template()
    {
        //constructor
    }

    public void DoSomething()
    {
        //does something
    }
    ...
}

and

public class PredefinedTemplate : Template
{
    public PredefinedTemplate()
    {
        this.Name = "Some Name";
        this.Description = "A description";
        this.Attribute1 = "Some Value";
        ...
    }
}

This solution is pretty similar to #2, but it ends up creating a lot of classes that don't really do anything (none of our predefined templates are currently overriding behavior), and don't have any methods, so I'm not sure how good a practice this is.

Has anyone else had any experience with something like this? Is there a best practice of some kind, or a different/better approach that I haven't thought of? I'm kind of banging my head against a wall trying to figure out the best way to go.

Thanks!

share|improve this question
    
The only 1 I wouldn't even consider choosing is option 3. You don't define a new class just because an instance contains different data values. Can you say "Class Explosion". –  Dunk Jun 5 at 15:17

2 Answers 2

up vote 1 down vote accepted

In a roundabout way, it sounds like you're grappling with a special case of the singleton pattern.

There are pros and cons to that pattern, with the primary benefit being that it will answer your immediate need and the primary drawback is that it takes solid governance to keep the singletons from bloating and deviating from their original purpose. SO and PSE have a number of threads related to the singleton pattern.

You'll end up with multiple singletons following the generic layout you specified in option 3. I would make them read-only and take advantage of whatever language features you have available for implementing those predefined instances of the templates.

I'd vote for option 3. It's not quite clear how your end users were intended to use these templates in the first place, but I don't think that knowing the full use case would change my answer.

If you were wanting to use the predefined templates as a means of pre-filling another template that was going to be modified for XYZ reason, then you could have additional constructors within the main template class.

public class Template
{
  ...
  public Template( Template predef )
  {
    //Copy in values from predef to this...
  }
}

... someOtherFunc()
{
  Template myTemp = new Template( predefTempFoo.Instance );
}
share|improve this answer

It looks like you are not using Java but in Java you can simply use this

public class Template{
   public static Template predefined1 = new Template("a", "b");
   public static Template predefined2 = new Template("c", "d");

   public Template(String a, String b) {}
}

Very simple and doesn't deal with any of the design pattern at all. Or you want something else with those templates?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.