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 looking for different ways to ensure that each instance of a given class is a uniquely identifiable instance.

For example, I have a Name class with the field name. Once I have a Name object with name initialised to John Smith I don't want to be able to instantiate a different Name object also with the name as John Smith, or if instantiation does take place I want a reference to the orginal object to be passed back rather than a new object.

I'm aware that one way of doing this is to have a static factory that holds a Map of all the current Name objects and the factory checks that an object with John Smith as the name doesn't already exist before passing back a reference to a Name object.

Another way I could think of off the top of my head is having a static Map in the Name class and when the constructor is called throwing an exception if the value passed in for name is already in use in another object, however I'm aware throwing exceptions in a constructor is generally a bad idea.

Are there other ways of achieving this?

share|improve this question

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

migrated from stackoverflow.com Oct 22 '12 at 17:51

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

1  
You want a singleton –  Marc B Oct 22 '12 at 17:45
5  
you should better go with the first one: - static factory –  Rohit Jain Oct 22 '12 at 17:46
15  
@MarcB op doesn't want singleton. he might have many instances of the same class, but these instances must be identifiable. –  BlueBullet Oct 22 '12 at 17:46
1  
@MarcB I'm aware of the singleton pattern but I thought that ensures only one instance of a class is possible? I want multiple instances, different values. Sorry if the question isn't making that clear. edit: Only saw first comment before posting. –  Peanut Oct 22 '12 at 17:48
2  
I'm aware that one way of doing this is to have a static factory that holds a Map... So why don't you want to do it this way? –  FrustratedWithFormsDesigner Oct 22 '12 at 17:55

5 Answers 5

Actually you have already answered your question. Your first way should be more effective here. Using static factory is always preferable than constructor wherever you think you can. So, you can avoid using Constructor in this case, else you would have throw some exception if an instance already exists with the given name.

So, you can create a static factory method: - getInstanceWithName(name) which will get the already available instance with that name, and if it does not exist, it will create a new instance, and make your constructor private, as it should mostly be done when dealing with static factories.

Also, for that you need to maintain a static List or Map of all the unique instances created, in your Factory class.

EDIT: -

You should certainly go through - Effective Java - Item#1 : Consider Static factories over Constructors. You can't get better explanation than that book.

share|improve this answer
1  
That's something which the OP already has thought of. –  BGurung Oct 22 '12 at 17:57
    
+1 for the link, which seems to clearly address some of the OP's concerns. –  Robert Harvey Oct 22 '12 at 18:15
    
@RobertHarvey. Yeah that book is the best source for most of the topics like these. And that's the very first item in fact. :) –  Rohit Jain Oct 22 '12 at 18:16
    
+1 for Effective Java, I do have the book, sitting in my bag now actually :) However I was just curious as to other ways of achieving the uniqueness apart from the static factory/static method and the exception in the constructor. If there aren't any then I'll accept this. –  Peanut Oct 22 '12 at 18:37
    
@Peanut. Sure. That is the best resource to dig in to get more information. –  Rohit Jain Oct 22 '12 at 18:48

Mentions of Effective Java seems to add a lot of credibility so this answer draws on:

  • Effective Java Item 8: Obey the general contract when overriding equals
  • Effective Java Item 9: Always override the hashCode when you override equals
  • Effective Java Item 15: Minimise mutability

I would take a step back and question why you care if there are more than one instance of this name object.

I rarely need to do this kind of object pooling. It is my guess that the OP is doing this so they can simply compare their Name objects with ==. Or use the Name objects inside a HashMap or similar as the key.

If so this is something that can be solved through proper implementation of equals().

Like so:

public final class Name {
  private final String name;

  public Name(String name) {
    if (name == null) {
      name = ""; //or exception if you like
    }
    this.name = name;
  }

  public String getName() {
    return name;
  }

  @Override
  public boolean equals(Object o) {
    if (!(o instanceof Name)) {
      return false;
    }
    Name other = (Name) o;
    return other.name.equals(name);
  }

  @Override
  public int hashCode() {
    return name.hashCode();
  }
}

Once done the following is true:

Name a = new Name("weston");
Name b = new Name("weston");
assert(a.equals(b)); //same but:
assert(a!=b); //not the same instance
//test out the Name instances in a hashmap:
HashMap<Name,Object> map = new HashMap<Name,Object>();
Object detailsIn = new Object();
map.put(a,detailsIn);
Object detailsOut = map.get(b);
assert(detailsIn==detailsOut); //the map returned the same details object
//even though we put with `a` and got with `b` thanks to our correct equals implementation

I'm guessing your goal, but this way you can use the Name class in hash maps etc, and they do not have to be the exact same instance.

share|improve this answer
    
Example, please. –  Robert Harvey Oct 22 '12 at 18:09
    
@RobertHarvey example of proper implementation? –  weston Oct 22 '12 at 18:11
    
Looks like you provided one. But I'm not clear how this is any different from merely checking the Name property for equality in a static factory method. –  Robert Harvey Oct 22 '12 at 18:13
1  
@RobertHarvey I've tried to explain more, I am offering a complete alternative that does not require static factory at all and I am challenging the OPs starting point that they do not want to have more than once instance per name. –  weston Oct 22 '12 at 18:40

you should make the constructors private and create methods like getNameInstance(String), if a object with the same name already exists (based on a static class' hastable for instance), you return that reference, else you create a new object using your private constructor and add it to the hashtable

share|improve this answer
    
You've repeated what I said in the 3rd paragraph of the question. I was after alternative ways. –  Peanut Oct 25 '12 at 0:53
    
I'm sorry, I think we answered almost at the same time because I checked for the answers before post mine. Actually, I tried to answer it on StackOverflown and than it was migrated. –  HericDenis Oct 25 '12 at 9:39
  • Make Name an interface
  • Create an interface NameFactory with a method Name getByName(String)
  • Create an implementation of NameFactory with a Map<String,WeakReference<Name>> inside it
  • synchronize on the map by name inside the getByName method before making new instances of Name
  • Optionally, use a static private implementation of the Name interface inside your implementation of the NameFactory

This approach would let you ensure that:

  • Only a single instance of Name exists at any time,
  • There is no "Lingerer" memory leak in your class, when Names stick around longer than they need to,
  • The design remains testable with mocked objects, because you use interfaces.
share|improve this answer
    
You don't have memory leaks with a factory method either, if you throw when the identical name exists instead of returning an object, or if you return a null object. –  Robert Harvey Oct 22 '12 at 18:26
    
@RobertHarvey I mean the leaks that are not really leaks, but legitimate objects (the so-called "lingerers"). A simple static map would prevent its value objects from being released, while a map of weak references would hold them in memory only for as long as other live references are in existence. –  dasblinkenlight Oct 22 '12 at 18:34
    
Ah, I see what you mean. This might be one of the rare instances where a destructor would be handy. –  Robert Harvey Oct 22 '12 at 19:30
1  
Too complex. It can be done like @weston answer, override equals and have the factory keep a collection of names. –  user61852 Oct 23 '12 at 1:59
    
@user1598390 One should make thing as simple as possible, but no simpler. weston's "solution" does not solve the OP's problem (there is no map), and a collection of names creates a lingerer memory leak (yes, there are memory leaks in Java). –  dasblinkenlight Oct 23 '12 at 2:06

Try following. You have to keep track of each object you create. For this purpose I'm using List. And made class constructor private, so that pre-check can be applied before creating an instance

class UniqueName
    {
        private string Name;
        public int ID;
        private static int Count=0;
        static List<UniqueName> lt=new List<UniqueName>();

        private UniqueName(string Name)
        {
            this.Name = Name;
            ID = ++Count;
        }

        public static UniqueName GetUniqueueInstance(string Name)
        {
            foreach (UniqueName un in lt)
            {
                if ( string.Compare( un.Name,Name,StringComparison.InvariantCultureIgnoreCase)==0)
                    return un;
            }

            UniqueName temp=new UniqueName(Name);
            lt.Add(temp);
            return temp;
        }
    }
share|improve this answer
    
This is not Java? Have you written a pseudo-code? Or, in any other language? Please specify that explicitly. –  Rohit Jain Oct 23 '12 at 13:01
    
Looks like C#. Akshay, you should learn other collections other than List. This would be a good fit for Dictionary<string,UniqueName>. –  weston Oct 23 '12 at 22:44

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.