This week’s post is pretty short. I’ve already , but this adds a personal touch. written about overengineering I had to rewrite my to use another data provider, switching from a Swiss one to a Bay Area one. One of the main components of the demo is a streaming pipeline. The pipeline: Jet Train demo Reads data from a web endpoint Transforms data through several steps Writes the final data into an in-memory data grid Most of the transform steps in #2 enrich the data. Each of them requires implementation of a . BiFunction<T,U,T> These implementations all follow the same pattern: We evaluate the second parameter of the . BiFunction If it is null, we return the first parameter; if not, we use the second parameter to enrich the first parameter with and return the result. It looks like this snippet: : JsonObject = ( == ) json JsonObject(json).add( , ) fun enrich (json: , : ?) JsonObject data String if data null else "data" data In the parlance of Object-Oriented Programming, this looks like the poster child for the Template Method pattern. In Functional Programming, this is plain function composition. We can move the null-check inside a shared function outside of the bi-function. : JsonObject = JsonObject(json).add( , ) : BiFunction<T, U?, T> = BiFunction<T, U?, T> { t: T, u: U? -> (u == ) t f.apply(t, u) } unsafeEnrich = BiFunction<JsonObject, String?, JsonObject> { json, -> unsafeEnrich(json, ) } safeEnrich = nullSafe(unsafeEnrich) fun unsafeEnrich (json: , : ?) JsonObject data String "data" data // 1 fun <T, U> nullSafe (f: < , U?, T>) BiFunction T // 2 if null else val data // 3 data val // 4 Move the null-check out of the function. Factor the null-check into a . BiFunction Create a variable from the function BiFunction Wrap the non-null-safe into the safe one BiFunction We can now test: println(safeEnrich.apply(orig, )) println(safeEnrich.apply(orig, )) null "x" It works: { : } { : , : } "foo" "bar" "foo" "bar" "data" "x" When I finished the code, I looked at the code and thought about the quote from Jurassic Park: Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should. I’m no scientist, but I felt it applied to the work I just did. I realized that I refactored in order to . When looking at the code, it didn’t look more readable and the code added to every function was minimal anyway. I threw away my refactoring work in favor of the . comply with the DRY principle WET principle There are two lessons here: Think before you code - this one I regularly forget. Don’t be afraid to throw away your code. Previously published at https://blog.frankel.ch/example-overengineering/