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've recently learned of MVC (model view controller) and am trying to refactor an existing program. I am in a situation where I'd like to have exactly one object of a particular class so it seemed evident that I should use a singleton. This singleton will be used to keep a hashmap of certain things. However this hashmap will have to be initialized when the singleton is created by reading nodes from a xml file and storing them as class objects.

Now my dilemma is:

  1. If I initialize the xml attributes (reading and converting to class objects), I'm effectively doing things in the model class that the controller should be doing, which is definitely not good.

  2. If I put the initialization method in a controller class, I would have to refer to a controller class from a model class, which does not conform to the MVC design.

  3. If I put the whole singleton in controller, then I'd have to look for the hashmap in the controller package, which defeats the purpose of having model classes.

  4. I can't pass a premade hashmap to the singleton as a parameter neither, because the constructor is private.. Well, I technically could, by giving it to the getInstance() method as a parameter, but it feels like a dirty way of fixing, since I now either pass null every time, or make another getInstance() method that doesn't accept a parameter.

Right now, my code is looking like this:

public class CategoryCatalog{

    private static CategoryCatalog categoryCatalog;
    private HashMap<CarOptionCategory, Set<ICarOption>> categoryOptionsMap;

    private CategoryCatalog(){
        categoryOptionsMap = new HashMap<CarOptionCategory, Set<ICarOption>>();
        initialize();
    }

    public static CategoryCatalog getInstance(){
        if(categoryCatalog == null){
            categoryCatalog = new CategoryCatalog();
        }
        return categoryCatalog;
    }

    private void initialize(){
        // TODO: xml
    }
}

Am I overlooking something or should I use a different approach?

share|improve this question

migrated from stackoverflow.com Mar 31 at 22:51

This question came from our site for professional and enthusiast programmers.

1  
The first point to realize is that any competent program will be made up of a number of different design patterns. MVC is a very useful design pattern for user interaction but it is not be-all and end-all of program design. For your singleton, you may want to use the factory pattern to have a factory class create the singleton. This has nothing to do with models or controllers. –  BobDalgleish Mar 31 at 23:48

1 Answer 1

up vote 0 down vote accepted

You have to use the right tool for the right problem. MVC is used to separate the representation logic from routing request logic (controller) and business logic (the model).

For creating objects you should use Creational Patterns. Now, in my opinion,

If I initialize the xml attributes (reading and converting to class objects), I'm effectively doing things in the model class that the controller should be doing, which is definitely not good.

It's good if the classes are used by the model.

If I put the initialization method in a controller class, I would have to refer to a controller class from a model class, which does not conform to the MVC design.

Yep, don't do this because a low lever layer should not depend of a higher layer.

If I put the whole singleton in controller, then I'd have to look for the hashmap in the controller package, which defeats the purpose of having model classes.

This singleton is not a controller so don't do that too.

I can't pass a premade hashmap to the singleton as a parameter neither, because the constructor is private.. Well, I technically could, by giving it to the getInstance() method as a parameter, but it feels like a dirty way of fixing, since I now either pass null every time, or make another getInstance() method that doesn't accept a parameter.

Yep, you will break encapsulation here because the hash map is an invariant of your class and if you accept a hash map it means that the invariant can be overwritten, maybe accidentally.

In my opinion this singleton is some kind of factory that provides classes, if the classes are used by the model, then put this singleton in your model package. also take a look at Spring, it will do this for you in a nice way.

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.