2

This is a design pattern academic question exercise. We have a Resource class and a pure fabrication class ResourcesManager to manage objects w/ type Resource.

The question is Given the following two definitions:

public class Resource {

}

public class ResourcesManager {

 public static Resource loadFromDb(int resID) {
   ...
 }
 public static Resource createNew(String name) {
    ...
 }
}

Apply Singleton pattern and Factory

My solution would be to apply Singleton and Factory both to ResourcesManager class. Since I need only one instance of the Manager, and it's the one in charge of creating new objects.

Some other student on the other side want to apply the Singleton to the Resource class.....

But If I think at the following execution on a possible client:

Resource r1 ResourcesManager = ResourcesManager.loadFromDb(1); Resource r2 ResourcesManager = ResourcesManager.loadFromDb(2);

I will have the unexpected behaviour that r1=r2.... Because they refer to the same Resource Singleton instance....

This is the solution I got in mind:

public class Resource {
     private String nome ;
     private int id;

     public Resource(){}

public void setName(String n){
    name=n;
}

public void setID(int n){
    id=n;
}

public String getName(){
     return name;
}

public int getID(){
     return id;
}

}



public class ResourcesManager {
  private static final ResourcesManager theInstance = new ResourcesManager();
  private ResourcesManager(){ }

  public static ResourcesManager getInstance(){
       return theInstance;
  }

  public static Resource loadFromDb(int resID) {
    Class.classForName(“Driver”);
    Connection con=DriverManager.get.Connection(...);
    Statement sta = con.createStatement();
    ResultSet rs = sta.executeQuery(“select name from resources where id=”+resID);
    if (rs.next){
              String name=rs.getString(“name”);
    }

    Resource s = new Resource();
    s.setName(name);
    s.setID(resID);
    return s; 
  }
  public static Resource createNew(String name) {
    Resource s = new Resource();
    s.setName(name);
    return s;
  }
}
1
  • I understand that my solution causes to have many instances of Resources loaded in memory. But how else to implement this if we need to load many resources at the same time to manage them? (i.e. order them)
    – koalaok
    Jan 9, 2016 at 10:46

1 Answer 1

2

This is a design pattern academic question exercise

Okay, in that case I'll leave out the standard "you probably shouldn't use singleton" essay!

My solution would be to apply Singleton and Factory both to ResourcesManager class. Since I need only one instance of the Manager, and it's the one in charge of creating new objects.

Some other student on the other side want to apply the Singleton to the Resource class.....

Well, you're right and they're wrong. A resource isn't the slightest bit appropriate for a singleton for precisely the reasons you say. In fact you already seem to know most of this, but let's explicitly list all the reasons:

  • Conceptually, you can have multiple different resources in your system. Trying to model that concept with a class that you can only have one of makes no sense.
  • Practically, you probably do want to actually be able to have multiple different resources in memory at once. There's nothing in the code or question to suggest you can rule out such a fundamental scenario.
  • If you did do this, you'd get the bizarre behaviour that loading a new resource would change an existing one you had hold of in a very unexpected way. This would horribly couple together every piece of code that wanted to use a resource, likely leading to "big ball of mud" code, bugs, and lack of testibility.
  • Having to be able to update the Resource means you'd have to make its fields mutable, which is something you usually want to avoid.
  • The question is clearly hinting this to you by having a Resource returned from the ResourceManager. If its behaviour was to just keep updating the existing resource then it'd be void, and you'd access the single Resource as a singleton.
  • Likewise the naming of the methods in the question. createNew reads to me like whoever wrote the question screaming into the page "Don't use a singleton for this!" A method called create new shouldn't update existing
  • There's absolutely no reason to think the memory you'd potentially save from the singleton solution would be singificant.

In fact, expanding on that last point, its really unlikely that you're going to save memory from the singleton solution in the first place. There's three possible scenarios:

  • You only ever use a single resource. In this case, both solutions would have the same performance, they create one Resource object.
  • You need multiple different resources in memory at the same time (e.g. stored in a collection). In this case, your solution is the only one that works at all.
  • You use multiple different resources, but only one at a time. In this case, it's questionable whether you'd ever end up with multiple Resource objects in memory anyway. It's likely that by the time you're creating the second one, the first will have gone out of scope, and will have been garbage collected.

    And in fact for there to be any possibility that the performance difference is significant, you'd have to use a large number of different resources, but only one at a time, but also do so in such a way that the ones you're done with don't go out of scope will you're loading the new ones. This is a really obscure and easily-fixed situation, and even then, it's likely that the memory overhead won't matter. So it's an extremely weak reason to base a decision on.


As a more general note, occasionally it happens that you need to go with a less expressive design which doesn't model the problem domain as well for performance reasons. If you think you're in this situation, there's two things you should do:

  • Resist it! It's actually pretty rare that this happens, so ask yourself is there a different, good design that meets your performance needs.
  • Isolate it. If you need to have something ugly somewhere, try to contain it so that only a small amount of other code needs to deal with that ugliness directly. A singleton is precisely the opposite- by definition it's system-wide! If you really found that creating multiple resources was a problem, it'd be a better, more isolated solution to change or add to your ResourcesManager's interface:

    public class ResourcesManager {
    
         public static void populateFromDb(Resource resource, int resID) {
           ...
         }
    
         public static void reset(Resource resource, String name) {
            ...
         }
    }
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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