Recently in Java Category

Statics Are Not Evil

| No Comments
So there I was with my newly scribed utility class complete with a clever little static factory method to make sure it gets instantiated properly.  I was wanting to try to set up the unit tests using Mockito, since I'd never played with that mocker before.  I eagerly dug into the docs to see how to get all hooked up.  And slammed headfirst into this claim in their FAQ:

Can I mock static methods?
No. Mockito prefers object orientation and dependency injection over static, procedural code that is hard to understand & change. If you deal with scary legacy code you can use JMockit or Powermock to mock static methods.

What a bunch of arrogant, self-righteous, ego-centric, lilly-livered[*], fingernail-clipping jerks!  How dare they judge my bundle of cleverness and joy!  They call my clean factory method hard to understand & change and scary based solely on the fact that it's static?  Inconsiderate blood-sucking little brats.

But then a chilling thought occurred to me... what if they're right?  *shudder*

Just so we're clear on the usage, here's an example code blurb of the type of thing I'm talking about.  This could be any old generic tool.

public class Tool<T>
{
  static public <T> Tool<T> getTool (Class<T> targetEntity)
  {
    Tool<T> fresh = new Tool<T>();
    fresh.setTargetEntityClass(targetEntity);
    return fresh;
  }

  private Tool ()
  {
  }

  :
}


I considered:

  • This is a utility class which includes a generic type.  Common patterns similar to this might be a sorter, a dao, a logger.  In other words, there are a lot of usages for this case.
  • Instantiating a one manually involves declaring the generic 3 different times.  Some value of the factory method is in reducing code clutter.  For example:
Tool<Library> libTool = new Tool<Library>(Library.class);
vs.
Tool<Library> libTool = Tool.getTool(Library.class);
(That seems a small thing, but as it's multiplied it becomes less small.)
  • This tool is used internally in many places for many different object types.  Wiring it through dependency injection would require a lot of wiring.
  • Perhaps most importantly, this is an internal utility class.

All in all, it doesn't make sense in any way to use dependency injection for this type of object.  Further, using a static factory provides code flow and cleanliness value, and is in no way procedural, hard to understand, hard to change, or scary.  The Mockito guys are wrong.

However, that still doesn't give me a way to test my beautiful code...


Footnotes:

* I don't know what lilly-livered means, but it's something I heard in Looney Toons often as a child.  If it's good enough for Yosemite Sam, it's good enough for me.

The Abomination of Anonymous Inner Classes

| No Comments
I have long held the opinion that the feature of anonymous inner classes in Java (and, truly, any language) are an abomination, an unnatural perversion having no place amongst all things Holy and True.  There are others who share this opinion of mine, for various reasons.

My primary reason for having such a severe dislike of those things is because they completely destroy the flow of the code.  In the middle of a method -- nay! even worse -- in the middle of a method call, suddenly there's code being laid out which will be executed in some other flow, most likely through some other thread -- nay! still worse -- suddenly there's another class being defined!  Lordy lord, what horrible thing to do to your code!

Let's look at a simple little example:

public class FindConfigFiles
{
  public void loadConfigFiles (File basePath)
    throws IOException
  {
    File[] configFileLIst = basePath.listFiles(new FileFilter ()
      public boolean accept (File toCheck)
      {
        return toCheck.getName().endsWith(".xml");
      }
    );
      :
  }
}


EEEK!  Don't do that!  Blech! Blech! Blech!

Instead, consider something like this:

public class FindConfigFiles
{
  static protected class ConfigFileFilter
      implements FileFilter
  {
    public boolean accept (File toCheck)
    {
      return toCheck.getName().endsWith(".xml");
    }
  }

  public void loadConfigFiles (File basePath)
    throws IOException
  {
    File[] configFileLIst = basePath.listFiles(new ConfigFileFilter());
      :
  }
}


Ahhhh.  Much better.  Just the act of turning that anonymous inner class into a named inner class worked magic on that little snippet of code.

That particular inner class only sported one line of meaningful code.  Now imagine if the code in the inner class had to be a bit more involved.  Even if the inner code were as small as 5 lines, the impact is still staggering.

You know, when all is said and done, the thing that really confuses me about this is that it seems most Java engineers don't even notice, or perhaps simply don't care, about the defilement they are incorporating into their very own code.

About this Archive

This page is an archive of recent entries in the Java category.

Ubuntu is the next category.

Find recent content on the main index or look in the archives to find all content.