17

In our Java codebase I keep seeing the following pattern:

/**
 This is a stateless utility class
 that groups useful foo-related operations, often with side effects.
*/
public class FooUtil {
  public int foo(...) {...}
  public void bar(...) {...}
}

/**
 This class does applied foo-related things.
*/
class FooSomething {
  int DoBusinessWithFoo(FooUtil fooUtil, ...) {
    if (fooUtil.foo(...)) fooUtil.bar(...);
  }
}

What bothers me is that I have to pass an instance of FooUtil everywhere, because testing.

  • I cannot make FooUtil's methods static, because I won't be able to mock them for testing of both FooUtil and its client classes.
  • I cannot create an instance of FooUtil at the place of consumption with a new, again because I won't be able to mock it for testing.

I suppose that my best bet is to use injection (and I do), but it adds its own set of hassles. Also, passing several util instances inflates the size of method parameter lists.

Is there a way to handle this better that I'm not seeing?

Update: since the utility classes are stateless, I could probably add a static singleton INSTANCE member, or a static getInstance() method, while retaining the ability to update the underlying static field of the class for testing. Does not seem super-clean, too.

9000
  • 24,162
  • 4
  • 51
  • 79
  • 1
    why don't you [pass an instance of FooUtil as constructor parameter of FooSomething](http://programmers.stackexchange.com/a/184472/31260 "as discussed eg here")? – gnat Jan 05 '15 at 20:50
  • 4
    And your assumption that _all_ dependencies need to be mocked to do unit testing effectively is not correct (though I'm still looking for the question that discusses that). – Telastyn Jan 05 '15 at 20:51
  • 4
    Why are these methods not members of the class whose data they manipulate? – Jules Jan 05 '15 at 20:52
  • @Telastyn: I see your point, but let's assume that _this_ particular dependency legitimately needs mocking sometimes. – 9000 Jan 05 '15 at 20:53
  • 1
    Then why does passing around a legitimate dependency bother you? – Telastyn Jan 05 '15 at 20:55
  • 1
    If it feels like you're passing it around too much, maybe it does too much. – Mike Partridge Jan 05 '15 at 21:03
  • @Telastyn: mostly because of the need to declare it in the parameter lists(s). I wish I could make it a part of the _context_, the way the `import` statement makes an external name a part of the context. – 9000 Jan 05 '15 at 21:04
  • Why aren't any of the methods `static`? Normally a utility class of this kind uses `static` methods, so that you can call `FooUtility.SomeMethod()` without having to instantiate the class or pass around an instance. – Robert Harvey Jan 05 '15 at 21:04
  • 3
    Have a seperate set of Junit that call the static fns if FooUtility. Then you can use it without mocking. If its someting that you need to mock then I suspect its not just a utility but doing some IO or business logic and should in fact be a class member reference and initialized via constructor, init or setter method. – tgkprog Jan 05 '15 at 21:08
  • 2
    +1 for Jules comment. Util classes are a code smell. Depending on the semantics there should be a better solution. Maybe the `FooUtil` methods should be put into `FooSomething`, maybe there are properties of `FooSomething` that should be changed/extended so that the `FooUtil` methods are not needed anymore. Please give us a more concrete example of what `FooSomething` to help us providing a good answer to this questions. – valenterry Jan 05 '15 at 21:28
  • 14
    @valenterry: The only reason util classes are a code smell is because Java doesn't provide a good way to have standalone functions. There are very good reasons to have functions that are not specific to classes. – Robert Harvey Jan 05 '15 at 21:30
  • 1
    These two questions are pretty similar to this one: https://programmers.stackexchange.com/questions/148049/how-to-deal-with-static-utility-classes-when-designing-for-testability https://stackoverflow.com/questions/4106260/is-it-acceptable-to-use-a-real-utility-class-instead-of-mocking-in-tdd @9000, if the answers to these questions don't apply to you, could you tell us what's different about your situation? – Ixrec Jan 05 '15 at 21:34
  • 1
    @valenterry sometimes you cannot add your methods to the Foo class because it is part of a core or third-party library. That is why you see `StringUtils` classes in several popular libraries. Now if `Foo` is a class that you control, then RobertHarvery's comment is more appropriate. –  Jan 05 '15 at 22:00
  • @valenterry If the functions don't need access to any of `FooSomething`'s private fields, I don't see why they ought to be instance methods. – Doval Jan 05 '15 at 22:17
  • 2
    @RobertHarvey Independent of Java you may be right that there are class or object agnostic functions. But there are very rare cases for this and I bet it is not the case here. Also read http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html – valenterry Jan 05 '15 at 22:19
  • @Doval: I did not say that it should be instance methods by all means. It is just one possible option, depending on the semantics. Please reread my comment again, I also wrote a different option there. – valenterry Jan 05 '15 at 22:21
  • @RobertHarvey I agree. Utility methods, combined with static imports, are a - lame, but what else? - way of emulating extension methods, for instance. Eg. Guava library wasn't written by cowboy coders, but there's plenty of static pure functions in it. – Konrad Morawski Jan 07 '15 at 01:22

2 Answers2

18

First of all let me say that there are different programming approaches for different problems. For my job I prefer a strong OO design for orginazation and maintenance and my answer reflects this. A functional approach would have a very different answer.

I tend to find that most utility classes are created because the object the methods should be on doesn't exist. This almost always comes from one of two cases, either someone is passing collections around or someone is passing beans around (These are often called POJOs but I believe a bunch of setters and getters is best described as a bean).

When you have a collection you are passing around, there must be code that wants to be a part of that collection, and this ends up being sprinkled throughout your system and eventually collected into utility classes.

My suggestion is to wrap your collections (Or beans) with any other closely associated data into new classes and put the "utility" code in actual objects.

You could extend the collection and add the methods there but you lose control of your object's state that way--I suggest you encapsulate it completely and only expose business logic methods that are necessary (Think "Don't ask your objects for their data, give your objects commands and let them act on their private data", an important OO tenant and one that, when you think about it, requires the approach I'm suggesting here).

This "wrapping" is useful for any general purpose library objects that hold data but you can't add code to--Putting code with the data it manipulates is another major concept in OO design.

There are many coding styles where this wrapping concept would be a bad idea--who want's to write a whole class when just implementing a one-time script or test? But I think encapsulation of any basic types/collections that you cannot add code to yourself is mandatory for OO.

Bill K
  • 2,699
  • 18
  • 18
  • This answer is so awesome. I had this problem (obviously), read this answer with some dubiousness, went back and looked at my code and asked "what object is missing that should have these methods". Lo and behold, elegant solution found and object-model-gap filled. – GreenAsJade Apr 30 '19 at 06:29
  • ["All problems in computer science can be solved by another level of indirection ...](https://en.wikipedia.org/wiki/Indirection) [... except for the problem of too many layers of indirection.](https://tools.ietf.org/html/rfc1925) – Deduplicator Apr 30 '19 at 21:42
  • @Deduplicator In 40 years of programming I've rarely (never?) seen the case where I was blocked by too many levels of indirection (aside from the occasional fight with my IDE to jump to an implementation rather than an interface) but I've often (Very Often) seen the case where people wrote horrible code rather than creating a clearly needed class. Although I believe too much indirection might have bitten some people, I'd error on side of proper OO principles such as each class doing one thing well, proper containment, etc. – Bill K Apr 30 '19 at 23:57
  • @BillK Generally, a good idea. But without an escape-hatch, encapsulation can really get in the way. And there is a certain beauty to free algorithms you can match to any type you want, though admittedly in strict-OO languages anything but OO is quite awkward. – Deduplicator May 01 '19 at 10:28
  • @Deduplicator When writing 'utility' Functions that must be written outside of specific business requirements you are correct. Utility classes full of functions (such as collections) are simply awkward in OO because they are not associated with data. these are the "Escape Hatch" that people who aren't comfortable with OO use (also, tool vendors must use these for very generic functionality). My suggestion above was to wrap these hacks in classes when you are working on business logic so that you can re-associate your code with your data. – Bill K May 01 '19 at 16:42
1

You could use a Provider pattern and inject your FooSomething with a FooUtilProvider object (could be in a constructor; only once).

FooUtilProvider would only have one method: FooUtils get();. The class would then use whatever FooUtils instance it provides.

Now that's one step away from using a Dependency Injection framework, when you'd only have to wire DI cointainer twice: for production code, and for your tests suite. You just bind FooUtils interface to either RealFooUtils or MockedFooUtils, and the rest happens automagically. Every object that depends on FooUtilsProvider gets the proper version of FooUtils.

Konrad Morawski
  • 9,721
  • 4
  • 37
  • 58