4 ms·
Totally agree with the concerns of the article. When you have to write a class of comparison functions like this in many types, it's arguably a violation of the
by jcrites 9y ago
Totally agree with the concerns of the article. When you have to write a class of comparison functions like this in many types, it's arguably a violation of the Don't Repeat Yourself (DRY) principle to implement comparison with unique, bespoke code in each type. Scenarios like this beg for a library or type system to make things easier.
In Java's case, a better solution is Guava's ComparisonChain:
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(this.aString, that.aString)
.compare(this.anInt, that.anInt)
.compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
.result();
}
There are similar utility methods for computing the object hashCode() and toString() and so on. See: https://github.com/google/guava/wiki/CommonObjectUtilitiesExplained https://github.com/google/guava/wiki/CommonObjectUtilitiesEx...
There's still an opportunity to make mistakes like typos here, but due to the visual consistency it's less likely. Actual logic errors in the comparison are also less likely.
A more powerful language than Java could potentially automate the entire implementation of methods like these (rather than just some of it), by reflecting over the set of fields in a class. Apache Lombok's annotations can kind of do this for a number of common boilerplate methods, though it looks like not yet for compareTo(): https://projectlombok.org/features/Data https://projectlombok.org/features/Data
C# properties are an example of an improvement over Java, for example, but C# class implementors are still responsible for dealing with implementing Equals(), GetHashCode(), and ToString() just like Java, as far as I know.
I would be interested to hear if there are any current programming languages that handle this use-case particularly well. Any Haskell, F#, or Scala folks out there who can comment?
- chusk3 9y agoF# records and tuples implement equality and comparison based on their members automatically, which handles the part that you mention that you're supported to do in C#. It's not reflection so much as at compile-time the compiler emits the correct implementation of these methods.
- tpxl 9y agoJava 8 also has `Comparator::comparing` and `Comparator::thenComparing`, so your code example above would be Comparator.comparing(Foo::getA). thenComparing(Foo::getB). thenComparign(Foo::getC); This makes much more sense than your example I think, since it will use the same getter on both methods, completely eliminating this class of errors.
- deleted 9y ago[deleted]