28

Over the last few months, I stumbled a few times over the following technique / pattern. However, I can't seem to find a specific name, nor am I a 100% sure about all its advantages and disadvantages.

The pattern goes as follows:

Within a Java interface, a set of common methods is defined as usual. However, using an inner class, a default instance is leaked through the interface.

public interface Vehicle {
    public void accelerate();
    public void decelerate();

    public static class Default {
         public static Vehicle getInstance() {
             return new Car(); // or use Spring to retrieve an instance
         }
    }
 }

For me, it seems that the biggest advantage lies in the fact that a developer only needs to know about the interface and not its implementations, e.g. in case he quickly wants to create an instance.

 Vehicle someVehicle = Vehicle.Default.getInstance();
 someVehicle.accelerate();

Furthermore, I have seen this technique being used together with Spring in order to dynamically provide instances depending on the configuration. In this regard, it also looks like this can help with modularization.

Nevertheless, I can't shake the feeling that this is a misuse of the interface since it couples the interface with one of its implementations. (Dependency inversion principle etc..) Could anybody please explain to me how this technique is called, as well as its advantages & disadvantages?

Update:

After some time for consideration, I rechecked and noticed that the following singleton version of the pattern was used far more often. In this version, a public static instance is exposed through the interface which is initialized only once (due to the field being final). In addition, the instance is almost always retrieved using Spring or a generic factory which decouples the interface from the implementation.

public interface Vehicle {
      public void accelerate();
      public void decelerate();

      public static class Default {
           public static final Vehicle INSTANCE = getInstance();

           private static Vehicle getInstance() {
                return new Car(); // or use Spring/factory here
           }
      }
 }

 // Which allows to retrieve a singleton instance using...
 Vehicle someVehicle = Vehicle.Default.INSTANCE;

In a nutshell: it seems that this is a custom singleton/factory pattern, which basically allows to expose an instance or a singleton through its interface. With respect to the disadvantages, a few have been named in the answers & comments below. So far, the advantage seems to lie in its convenience.

  • some kind of singleton pattern? – Bryan Chen Dec 16 '13 at 5:04
  • I think you're right that the interface shouldn't "know" about its implementations. Probably Vehicle.Default should be moved up into the package namespace as a factory class, e.g. VehicleFactory. – augurar Dec 16 '13 at 6:43
  • 7
    By the way, Vehicle.Default.getInstance() != Vehicle.Default.getInstance() – Konrad Morawski Dec 16 '13 at 8:13
  • 20
    The antipattern here is to use the car-analogy antipattern, closely related to the animal-analogy antipattern. Most software doesn't have wheels or legs. – Pieter B Dec 16 '13 at 8:32
  • @PieterB: :-)))) You made my day! – Doc Brown Dec 16 '13 at 10:57
24

Default.getInstance is IMHO just a very specific form of a factory method, mixed up with a naming convention taken from the singleton pattern (but without being an implementation of the latter). In the current form this is a violation of the "single responsibility principle", because the interface (which already serves the purpose of declaring a class API) takes the additional responsibility of providing a default instance, which would be much better placed in a separate VehicleFactory class.

The main problem caused by this construct is that it induces a cyclic dependency between Vehicle and Car. For example, in the current form it won't be possible to place Vehicle in one library, and Car in another. Using a separate factory class and placing the Default.getInstance method there would solve that problem. It may be also a good idea to give that method a different name, to prevent any confusion related to singletons. So the result could be something like

VehicleFactory.createDefaultInstance()

  • Thanks for your answer! I agree that this particular example is a violation of the SRP. However, I'm unsure whether it is still a violation in case the implementation is dynamically retrieved. E.g. by using Spring (or a similar framework) in order to retrieve a particular instance defined by for example a configuration file. – Jérôme Dec 16 '13 at 22:07
  • 1
    @Jérôme: IMHO a non-nested class named VehicleFactory is more conventional than the nested construct Vehicle.Default, especially with the misleading "getInstance" method. Though its possible to circumvent the cyclic dependency by using Spring, I would personally prefer the first variant just because of common sense. And, still it leaves you with the option of moving the factory to a different component, changing the implementation afterwards to work without Spring etc. – Doc Brown Dec 17 '13 at 8:54
  • Oftentimes, the reason for using an interface rather than a class is to allow classes which have other purposes to be usable by code which needs an interface implementation. If a default implementing class can meet all of the needs of code which simply needs something that implements the interface in "normal" fashion, specifying a means of creating an instance would seem a useful thing for the interface to do. – supercat Feb 24 '14 at 2:33
  • If Car is a very generic, standard implementation of Vehicle, this is not a violation of SRP. Vehicle still has only a single reason to change, e.g. when Google adds an autodrive() method. Your very generic Car must then change to implement that method, e.g. by throwing an NotImplementedException, but that does not confer an additional reason to change on Vehicle. – user949300 Oct 2 '14 at 20:51
  • @user949300: the SRP is not a "mathematical provable" concept. And software design decisions are not always "black-and-white". The original code is not so bad it could not be used in production code, of course, and there may be cases where the convenience outweighs the cyclic dependency, as the OP has noted by himself in his "update". So please read my answer as "consider if using a separate factory class does not serve you better". Note also the author changed his original question a bit after I gave my answer. – Doc Brown Oct 3 '14 at 5:11
3

This looks like Null Object pattern to me.

But that heavily depends on how Car class is implemented. If it is implemented in "neutral" way, then it is definitely a Null Object. That means, if you can remove all null checks on the interface and put instance of this class instead of each occurrence of null, then code still has to work correctly.

Also if it is this pattern, then there is no problem of creating tight coupling between the interface itself and implementation of null object. Because null object can to be everywhere where said interface is used.

  • 2
    Hello and thanks for the answer. Although I'm pretty sure that in my case this wasn't used to implement the "Null Object" pattern, it is an interesting explanation. – Jérôme Dec 16 '13 at 22:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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