Hiding utilities behind a facade

Recently, at work, I got into a passionate discussion about whether we should hide things like StringUtils behind a facade.

I was helping a coworker add some tests around a monstrous method and noted that it used StringUtils static methods quite a few times in the method.  Initially I thought that this was a utility class that we had written, so rather than changing the class to have non-static methods, I opted to try to hide it behind a facade (in this case it was a simple pass-through object, but the methods on this object were non-static, thus allowing me to mock it with Mockito).  Upon investigation, it turned out we were using commons.lang StringUtils.  Still, I thought it might be good to put it behind a real object so we could mock it out.

I explained to my colleague that the reason I wanted to do this was so that we didn’t have to set up our tests with realistic data.  We could pass in very fake data and we could make sure that we were only testing the method in question (which was VERY important since it was a behemoth).  By putting it behind the facade, we were able to make it return whatever we wanted.

We spent the morning getting this all set up and she was ready to start off on her own in the afternoon.  Later that afternoon, she was talking with the other developer (and our boss), who works in the code base in question regularly about the tests she was writing.  He did not agree at all about us mocking out StringUtils.

A very heated discussion ensued.  In the end, since I didn’t work in the code in question, I left it up to them how they wanted to test it.

After the discussion, I was reflecting on why I felt so strongly about mocking out StringUtils, and I think I have pinpointed some of the reasons.

  1. The method under test was doing a LOT of things, including calling out to StringUtils nearly a dozen times for different things.  By mocking out StringUtils I felt more comfortable that we were tackling the code that was in the method without having to worry about what StringUtils was going to do with the data we passed it.  I was trying to reduce the complexity of the method in question by ensuring I was using things I had complete control of.
  2. I saw StringUtils as a collaborator and wanted to make sure that I was testing only the method in question, and not the collaborating code.  I believe I saw it this way due to point 1.
  3. I knew that we had some other classes in the code base that had a bunch of static methods on them.  I would treat these the same way.  Rather than treating each different class with static methods differently based on some gut feeling, I wanted to be consistent and treat any class that offered static methods the same way.  This allows me to focus on the tests, rather than spending mental cycles on deciding whether this particular things should be mocked or not.
  4. Hiding a 3rd party tool behind a facade is a best practice I have heard many times.  It allows you to swap out the tool for a new one with little effort.  It can also make it much easier to upgrade to a new version, even if the new version has changed the API, since if everyone using it is actually using the facade, you only need to make the change in one place, and everyone else just continues using the facade in the same way as they always had.

 

 

Simply refactoring the monolithic method into smaller methods that could do each individual task would have left me testing it much differently.

Challenge your preconceptions

I worked with a gentleman once upon a time whose ideals around software development were the polar opposite of mine.  He held a higher position in the company than me or my team and we often suffered from decisions he made.

For many years we worked at the same company, but never on a project together and for that I was thankful.  Then, one fateful day I was put on a project alongside him.  I was hoping that he would simply act as a domain expert and leave the software planning to me.

Alas, that was not meant to be.  I walked into his office to talk about how we were going to tackle this project, expecting to have to defend my approach and found out that he was very receptive to my ideas.  As we continued to work together, I was continuously surprised that we held the same views on a number of things.  There were still things that we held opposing views on, but there were certainly a lot more points where we agreed than I would ever have imagined.

Sound familiar?

Is there someone that you work with, or know, that you think is your opposite?  They don’t believe in anything that you do?  They are stubborn and unwilling to change or listen to your ideas?

I think we all have someone like this in our lives.  I would challenge you to get to know that person a little better.  Talk to them, take them to lunch (a group lunch might work well if there is a lot of animosity between the two of you).  Try to drop all of your preconceived notions about them and learn who they really are.  You probably have a lot more in common with them than you would ever have realized.

If you can see someone as “like you” rather than “other”, working with them will become much easier.  You will be more likely to empathize with them than demonize them.

Design Principle: Encapsulate what changes

Principle

Encapsulate or isolate the parts of your system that change more often.

We can accomplish isolation in many different ways.  For example, we can simply separate out the parts of the code (or objects) that are likely to change into separate classes.

Another option that comes to mind is configuration files (or any type of external configuration).  These can include data (like a copyright notice) that might change depending on the deployment, as well as feature switches, or information on which style of a class to load.

Concerns

Shouldn’t I keep the behaviors of an object together in one class, rather than separating it out?

Yes.  However, isolating the parts that change doesn’t need to mean that your object doesn’t define what behaviors it has.

We use helper methods all of the time.  Sometimes it is to perform a calculation that we need to perform in many different places.  When we use a helper class to do some of this work, we will define a method on our object of interest, and have it simply call through to our helper.

For Example:

public class InterestingObject {
   private HelperObject helper;
   public InterestingObject(HelperObject helper) {
      this.helper = helper;
   }

   public void interestingFunctionality() {
      helper.interestingFunctionality();
   }
}

public class HelperObject {
   public void interestingFunctionality() {
      // some interesting functionality here
   }
}

When working with our InterestingObject, we now know that it has interestingFunctionality.  When working with that object, we don’t need to care that there is a helper object that is implements that functionality.

Why does it matter if I change some parts of a class more often than other parts?

First of all, making modifications to a class violates the open/closed principle which states that we should have our classes open to extension but closed to modification.  Granted, it is not always possible to follow this principle.

Imagine you have a class that has behaviors.  In that class, you will likely have some instance variables that you share in several methods.  Now, imagine that you need to change the data structure for one of those variables because you need it in a more convenient form for a new calculation.  In order to switch that data structure, you will need to touch all of the methods that use that data.  If, however, that method lived in a different object it would be free to use a new data structure to do the computation, as long as the API remained the same and it could still return the same type of object/data structure.

What I am getting at with all of those words is that methods inside a class can often be tightly coupled with one another, and that is ok.  However, when you need to touch one, you often have to touch others.  If you have those methods in separate classes, you can often get away with making a change just to the methods in question without having to touch the calling code.

What is all of this work really buying me?

Ideally this is buying you a safety net.  It is allowing you to ensure that the changes you make are only going to impact a small piece and only the piece that you intend.

If you have pulled out some things into a configuration file or table, you can often make changes to your application without even having to rebuild it.  Just make a change to the configuration and restart and viola!

 

How to convert a String to an Enum

The other day I was asked how to take an input string and convert it into an enum.  The individual in question searched the nets to no avail…so, this seemed like a good opportunity to impart some knowledge that is apparently hard to find.

public enum Fruit {
  APPLE("apple"), BANANA("banana"), PEAR("pear");

  private String fruitName;

  private Fruit(String fruitName) {
    this.fruitName = fruitName;
  }

  public convertToEnum(String stringToConvert) {
    for(Fruit fruit: Fruit.values()) {
      if(fruit.fruitName.equalsIgnoreCase(stringToConvert)) {
        return fruit;
      }
      return null;
    }
  }
}

In words, we construct our Enum with strings that represent the particular enum (you could probably get away with just using the name of the enum, rather than adding the string representation).  Then you simply create a convert method that can loop through the values of the enum (which is all of the enumerated values defined, in this case APPLE, BANANA and PEAR), and compare the string sent in to the string representation ignoring case and return the matching enum.

By accessing the enum.values(), you can easily add additional enumerated values without changing any of the rest of the Enum.