9

Let's say that I want to build some utility functions to do some basic maths with the BigDecimals, for example I want to have a function that computes the average of a List<BigDecimal>.

What is the best approach? A static function or a utility class?

public static BigDecimal computeAverage(List<BigDecimal> numbers)

or

public class BigDecimalUtil

public computeAverage(List<BigDecimal> numbers)
1
  • A point to consider, is to identify which class has the responsibility to do this calculation. You may discover that this functionality is not globally required by other classes and hence it may be a private method in 1 class. Another thing to consider is static definitions and thread safety.
    – NoChance
    Feb 22, 2012 at 9:53

6 Answers 6

9

I'm probably going to give away my C# leanings in the worst possible way, but I'd always recommend static methods within utility classes. This gives you the best of both worlds. The organizational benefits of the class with the usability of methods accessed without needing to instantiate an object to use them. If your utility class has a reason to occasionally vary its behaviour, then you are already well positioned to do so by introducing inheritance/interfaces later should you need to. If you wish your design to be a little more portable, then you'll find the paradigm will more easily transfer to other OO languages.

5
  • "If your utility class has a reason to occasionally vary its behaviour": yeah but I am in a java shop and you cannot change a static method by extending the class.
    – S4M
    Feb 19, 2012 at 16:51
  • @S4M Naturally if your method behaviour needs to change, then you're going to need to rethink the design. As I said in my answer however, if you do need to alter the design, you are well positioned to do so. You can always refactor the method to be non-static if you do need the behaviour to be extended. If you have all of your methods dotted all over the place then you are going to have difficulty locating them. Naturally if the method is only needed by a single class, then you would be better off leaving it within that class, in which case the issue of being static or not becomes irrelevant.
    – S.Robins
    Feb 19, 2012 at 19:44
  • Actually I am a big fan of static methods myself, but in my company I noticed a senior dev using non static methods, so this got me thinking. Basically I would to ListBigDecimalUtils.computeAverage(x) while he would do new AverageListBigDecimal().calculate(x). I don't see the benefit of his approach.
    – S4M
    Feb 19, 2012 at 20:53
  • @S4M It may simply allow him to provide his methods with access to other non-static methods within his class. Granted however that these could be simply additional private static methods. More likely perhaps is that he is ensuring he leaves himself options to extend the class should he see a need on the future. Better perhaps to ask you senior developer what his reasoning is if you want to understand where he sees the benefits.
    – S.Robins
    Feb 19, 2012 at 21:05
  • @s4m. I think simple non-miscellaneous static classes fine and maybe the best choice for now (shame that java lacks extension method btw). But a "statsservice" isn't silly either. I could imagine having the need to change Average from mean to median to trimmed mean at runtime. I can ready imagine maths operations on lists of ints that produce entropy and would require a service for testability.
    – Nathan
    Mar 19, 2015 at 0:50
5

If you want to do utility functions, connected by some theme, make a class for them, make them static in that class and make a constructor of that class private, to eliminate the possibility of accidental giving out an instance. So, use the second variant, but hide the constructor.

public class BigDecimalUtil

public computeAverage(List<BigDecimal> numbers)

private BigDecimalUtil(){super();}

There is one more possibility - to make no constructor and make this class abstract. But on this way you can't use instance of the class not only outside, but also inside it. So, I think, this second variant is too strict for you. Choose yourself.

4

I agree with @Gangnus that a static "wrapper" class makes sense if individual class methods will always be used in isolation, and this is often going to be a good answer.

However, there might be some value in a non-static class, with non-static methods, if you have related calculations likely to be used together. For example, construct a ListStatsUtil object with List<BigDecimal> passed into constructor, it might be convenient to access getStandardDeviation, getVariance, and getAverage in sequence without passing back in the object. This may be more elegant, but might also perform better, especially if computationally expensive operations are involved that can be optimized across operations by sharing private state within the object.

public ListStatsUtil {
    private final List<BigDecimal> numbers;
    public ListStatsUtil(List<BigDecimal> numbers) {
        this.numbers = numbers;
    }
    public BigDecimal getAverage() {
        // return average of this.numbers
    }
    public BigDecimal getStandardDeviation() {
        // return std dev of this.numbers
    }
    public BigDecimal getVariance() {
        // return variance of this.numbers
    }
    public BigDecimal getMax() {
        // return max of this.numbers
    }
    public BigDecimal getMin() {
        // return min of this.numbers
    }
}
6
  • I don't have permission yet on this new programmers site to leave a comment for @Gangnus, so I will leave it here. Does the super() in the private constructor make sense for a static class in Java? Feb 19, 2012 at 2:53
  • Without any doubt, it has sense only as a self-discipline of for the case of future radical refactoring. We want this constructor never to be run.
    – Gangnus
    Feb 19, 2012 at 21:08
  • I don't understand. All these functions, as getVariance and such, take List<BigDecimal> and return BigDecimal of double. How could you put them in chain? The idea of chaining utilities is good, but a) not for the case provided by you. b) not in the case about which is the question. It is for the case when we need a new class with utilities. So, such question never rises - answer is obvious.
    – Gangnus
    Feb 19, 2012 at 21:15
  • Not in a chain, just that you might want multiple operations on the single list. The question did not preclude this possibility. Feb 19, 2012 at 21:34
  • The class that I have described, can easily define such methods. It only doesn't give any instance out, but can use them inside OK. In this case, of course, the constructor becomes a working one, but we have prepared for it, haven't we? :-)
    – Gangnus
    Feb 19, 2012 at 21:39
2

I voted for codingoutloud answer and I'd like to expand on it a little.

Wrapping collections in classes is something I've come to try to always do--my rule is "Never pass a naked collection". The biggest failures of OO I've seen is when people are afraid to add methods where they belong. In your case the methods belong on the collection (Totally obviously if you think about it), so put them there by wrapping the collection, and to put the icing on the cake, only expose the functionality you need outside your new class (as codingoutloud did) so that you can look at your single, small class and easily understand everything manipulating that collection.

You don't have to solve every possible problem because it's all your code, you can edit the collection wrapper just as easily as you can edit the other classes that interact with it. This lets you pull other code into the class as necessary--if you don't ever expose the collection it will become quickly obvious what code belongs in the wrapper.

This also gives you complete control over the collection so you can prevent it from getting into a state inconsistant with it's function (For instance, if no entry in the collection can be null, just prevent anyone from putting a null in!)

Most of the bad OO code I've ever seen has been created because someone chose to write static utilities or inline code that belonged in objects they couldn't add code to instead of wrapping the offending objects in code of their own that they could modify.

2
  • In this particular case I would say average was a reasonable method to invoke on any collection of numbers. So you could end up just giving all your number containers new names with a bit more functionality. Sounds like bad return on effort. This is what extension methods are for in c#, in java you're stuck with statics.
    – Nathan
    Mar 19, 2015 at 1:01
  • Utilities without business logic often don't have a good OO solution and the best you can do is static classes and fixed classes like collections. If you really must do a general purpose utility you might as well abandon oo like collections, math util and all the other utilities do. In this case, he probably is just using one collection for his business code so why implement a general solution?
    – Bill K
    Mar 19, 2015 at 1:14
0

If I'm not wrong and Java cotinues to be a pure OO language, you cannot have functions without wraping them in a class.

So your answer is: both, a static function wraped in a static utility class, not unlike Math class.

-2

How about a CalcAverageStrategy interface that is injected, and you can then have mean/median/mode implementations injected where necessary.

Each implementation is easy to test, and also easy to mock for testing.

1

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