views:

246

answers:

4

Back couple of months ago I attended a presentation hosted by two representative of an independent software development company. It was mainly about good software design and practices.

The two guys were talking mainly about Java and I remember them saying, that in some circumstances it is very good practice to use getInstanceOf() instead of the constructor. It had something to do with making always calling getInstanceOf() from different classes rather than constructor and how it was it is much better approach on larger scale projects.

As you can see I cannot remember much from it now :/ but I remember that the arguments that they used were really convincing. I wonder if any of you ever came across such a design and when, would you say, is it useful? Or do you think it isn't at all?

+1  A: 

I suspect you mean the newInstance method on the Class class. You would invoke it like this: MyClass foo = MyClass.newInstance();

This form of object instantiation is popular in creational patterns; it's useful when you want to specify the concrete, runtime type of an object externally, such as in a properties or XML file.

Drew Wills
However: `Class.newInstance()` is evil as it can throw checked exceptions which aren't declared. It may be better to use `Constructor.newInstance()` which throws `InvocationTargetException`. See http://stackoverflow.com/questions/195321/why-is-class-newinstance-evil
Simon Nickerson
@Simon Nickerson - This is good, insightful information. But I'm not convinced it actually makes newInstance() 'evil'; you can make your own determination about whether Java's compile-time exception checking is valuable or not. I'm not a fan myself (it worsens the signal:noise ratio in source code), though I recognize this is one area where reasonable people disagree. Consider Groovy: that community deems the fact that Groovy code treats private methods as public to be a "feature."
Drew Wills
Whether or not you disagree with Java's checked exceptions, `Class.newInstance()`'s behaviour is certainly surprising. Evil is a little strong perhaps :), but I think it was a mistake to allow it to subvert the checked exception mechanism in this way.
Simon Nickerson
+1  A: 

If Drew is right, newInstance() is part of the Java Reflection API. So it is not as natural as using a constructor.

Why it would be recommended to use it on a large project may come with the fact that it leads to Java Bean programming style and clearly makes the creation of the object something particular. On large project, creating object shouldn't be a cross-cutting concern but rather a clearly identified responsibility, often from one source / factory. But IMHO, you get all of those advantages and many more with IoC pattern.

Hubert
+6  A: 

Consider static factory methods instead of constructorsJoshua Bloch

trashgod
+4  A: 

They were probably talking about the static factory method pattern (and not the reflection API method for dynamically creating objects).

There at several advantages of a method such as getInstanceOf() over a constructor and using new. The static factory method can...

  1. Choose to create a different sub-class of the main class if that is desirable in certain cases (based on environmental conditions, such as properties and other objects/singletons, or method parameters).

  2. Choose to return an existing object instead of creating one. For an example of this, see Boolean.valueOf(boolean) in the Java API.

  3. Do the same thing as the constructor - just return a new instance of the class itself.

  4. Provide many different kinds of ways to construct a new object and name those methods so they are less confusing (e.g. try this with constructors and you soon have many different overloads). Sometimes this is not even possible with constructors if you need to be able to create an instance two different ways but only need the same type of parameters. Example:

    // This class will not compile!
    public class MyClass {
        public MyClass(String name, int max) {
            //init here
        }
        public MyClass(String name, int age) {
            // init here
        }
    }
    
    
    // This class will compile.
    public class MyClass2 {
        private MyClass2() {
        }
        public static MyClass2 getInstanceOfMax(String name, int max) {
            MyClass2 m2 = new MyClass2();
            // init here
            return m2;
        }
        public static MyClass2 getInstanceOfAge(String name, int age) {
            MyClass2 m2 = new MyClass2();
            // init here
            return m2;
        }
    }
    
  5. Do any combination of the above.

  6. And, on top of all that it hides the detail of instantiating an instance from other classes and so can be varied in the future (construction encapsulation).

A constructor can only ever create a new instance of an object of the exact type requested. It cannot be varied later.

Some disadvantages of this pattern are:

  1. The factory methods are static so cannot be inherited in sub-classes; a parent constructor is easily accessible to sub-classes.

  2. The factory method names can vary widely and this could be confusing for some (new) developers.

You also asked for personal experience. Yes, I frequently use both patterns. For most classes constructor but when there are much more advanced needs then I use the static factory. I also work on projects in other languages (proprietary, but similar to Java) where this form of construction is mandated.

Kevin Brock