Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create one object instance per class in hierarchy

I was asked this question in an interview.

There are 3 classes A, B extends A & C extends B. We have to design these classes conforming to these constraints

  • Client can instantiate only one instance of A, one instance of B & one instance of C using their default constructor with new keyword.
  • Trying to create another instance of any of these class will result in an exception.
  • The designer of the class have to enforce the above 2 rules, so that client will experience the above rules implicitly (i.e. it should not be the responsibility of client to conform to above rules).

I suggested an approach using an static Map<Class, Object>. So for e.g. when somebody called new B() it would check if map.contains(B.class). If yes then throw exception & if not then save instance in map & let the object be created.

But the next question was how would I enforce this approach on each class? As per my approach each constructor would have to carefully populate the map otherwise it will break the constraint.

How would I solve this problem?

like image 822
Master Chief Avatar asked May 27 '19 14:05

Master Chief


People also ask

How do you create an instance object of a class?

Instantiating a Class When you create an object, you are creating an instance of a class, therefore "instantiating" a class. The new operator requires a single, postfix argument: a call to a constructor. The name of the constructor provides the name of the class to instantiate.

Can you create more than one instance from a class?

The result of this is that you have two reference variables that point to the same object. You can use the same reference variable to create more than one instance of a class.

Can you create an instance of an object?

To create a new instance of an object, we use the "new" keyword. This keyword creates a new instance of an object, which we can then assign to a variable, or invoke methods.


1 Answers

But the next question was how would I enforce this approach on each class? As per my approach each constructor would have to carefully populate the map otherwise it will break the constraint.

Simply by putting that map, and the code around it into some distinct Utility class. So that each and of your classes could do something like:

public WhateverClassConstructor() {
  synchroized(someLock) {
     SingeltonChecker.ensureUnique(this);

with

 public static void ensureUnique(Object objectToAdd) {
   Class<?> classToAdd = o.getClass();
   ...

And given the fact that C extends B extends A, you probably only need that call in the constructor of class A. On the other hand, imagine that your first call to new C() causes an exception with the C-constructor, but a second call would not. Sure, that is a problem in itself, but still, the question remains: how do you ensure an object was fully and correctly initialized before adding it to such a map?!

Thus: there is a ton of things to consider when writing such utility code. Thus my answer would focus on the impractically, almost stupid-ness of the given design point, and suggest to throw it away and go for other solutions, for example something as simple as:

public enum SingletonObjectHolder {
  private final Object hold;
  A_INSTANCE(new A()), B_INSTANCE(new B())...

  public Object getSingleton() { return hold; }
  private SingletonObjectHolder(Object o) { hold = o };

Don't waste too much time trying to give people a technical answer, when the real point is to not shoot yourself into the foot. And make no mistake: getting that map-based "singleton" approach to work robust and correct, for all kinds of contexts, consider that really hard.

In other words: if I would ask you this question in an interview, I would want to hear an answer that challenges that horrible design point. Sure, spent 10% of your time outlining a solution for the given scenario. But spend 90% of the time explaining why it is so bad, and why other solutions would be much better.

like image 95
GhostCat Avatar answered Sep 19 '22 02:09

GhostCat