Dependency Injection vs Functional

At work, we use dependency injection to build up small, decoupled classes each with a single responsibility. DI lets us assemble these in multiple different ways, so we can use the same class for similar processes. This strategy of combining small pieces of functionality in different ways is also a goal of functional programming. Let’s contrast the two methods.

There’s a chunk of code whose job it is to string together the contents of a list of segments. The contents can be in one of two different fields in the segments. The segments might have connectors, which might need to go between the contents. We might need to skip the first and last segment if they’re not interesting.

To avoid duplication of any part of this, our current Spring-y solution at work uses dependency injection to construct different SegmentContentsConcatenators with different components. The result is 9 Java classes and 6 Interfaces.

  • Builder
    • has a SegmentRemover (or a not-remover)
    • has a Concatenator
      • has a ConnectorRetriever (or a not-retriever)
      • has a first-or-lastness determiner
      • has a ContentExtractor (two implementations, one for each possible field)

The Spring configuration defines 3 beans that are useful, but in order to hydrate these in all possible combinations, 17 bean definitions are required. Fortunately for us we care about three of the eight possible behaviour combinations, so we only need 12 bean definitions. Only!

That’s a at least 120 lines of Java in 15 files, plus about 30 lines of XML. Not counting tests.

Just for fun, I implemented the same functionality in F# using The result is 12 little function (including two that are generic and could be placed in a list-processing library). It took 30 lines of F# code. The functions build on each other, and the three desired functionality combinations are pieced together from other small functions. Best of all, there’s no XML at all!

Both methods have the same goal: take small, testable pieces of functionality and piece them together in multiple ways. This is what functional languages DO. Trying to achieve the same goal in Java with Spring was not so pretty.

For reference, here’s the F# code:

// defining the types
type Contents = string

type ConnectorMethod =
| Easy
| Complicated of Contents

type Segment = { ExpectedContents : Contents; ObservedContents : Contents; Connector : ConnectorMethod; IsExtraneous : bool;}

// Functions that build up all the pieces
let findConnector c : Contents =
match c with
| Easy -> ""
| Complicated x -> x

let expected s = s.ExpectedContents
let observed s = s.ObservedContents

let expectedInternalJunction s = expected s + findConnector s.Connector

let rec concatSegmentsInternal f fIJ acc list =
match list with
| [] -> acc
| [x] -> acc + f x
| head :: tail -> concatSegmentsInternal f fIJ ( acc + fIJ head ) tail

let concatSegments f fIJ l : Contents =
match l with
| [] -> ""
| x -> concatSegmentsInternal f fIJ "" l

let isExtraneous s = s.IsExtraneous

// these last two are generic, could apply to any predicate and list
let rec removeLastIf s l : 'a list =
match l with
| [] -> []
| [x] when s x -> []
| [x] -> [x]
| head :: tail -> head :: (removeLastIf s tail)

let removeEndsIf s l =
match l with
| [] -> []
| head :: tail when s head -> removeLastIf s tail
| head :: tail -> head :: removeLastIf s tail

// Publically useful methods - these put the pieces together.
let concatExpectedSegments : Segment list -> Contents = concatSegments expected expectedInternalJunction
let concatObservedSegments : Segment list -> Contents = concatSegments observed observed
let concatInterestingObservedSegments ss : Contents = concatSegments observed observed (removeEndsIf isExtraneous ss)

// Tests
let s1 = {ExpectedContents = "ABC"; ObservedContents = "ABCD"; Connector = Complicated "-"; IsExtraneous = true;}
let s2 = {ExpectedContents = "EFG"; ObservedContents = "EFGH"; Connector = Complicated "a"; IsExtraneous = false }
let s3 = {s1 with IsExtraneous = false}

let ss = [s1;s2;s3]

assert (concatExpectedSegments ss == "ABC-EFGaABC")
assert (concatObservedSegments ss == "ABCDEFGHABCD" )
assert (concatInterestingObservedSegments ss == "EFGHABCD")

Spring configuration returns home

Remember the early days of XML, when people were all excited about using it to wire up applications? “You can change which implementation is used without changing any code!”

Sure, right, XML isn’t code. It gets packaged in your jar files, with the code. It controls how your application works, like the code. It breaks shit when it is wrong, like the code. Difference is, it’s a lot easier to test the code.

I’m happy to see that Spring is coming full circle and moving configuration back to the code. Not to application code (in-bean annotations), but to separate configuration classes. This keeps the wiring isolated from the application code, while keeping the configuration readable, refactorable, and more testable.

Instead place of XML, we get something like this:

public void ZooConfig {

public Goat goat() {
return new GoatImpl();

public PettingZoo pettingZoo() {
PettingZoo p = new PettingZooImpl(goat(), goat());
return p;


Yes, this is a trivial made-up example. What is exciting about it?
– The compiler finds the typos in your class names.
– The IDE (without any special plugins) links between the application code and configuration. I can get from here to the implementation class quickly. The configuration will show up in a “Find Usages” search. If I rename GoatImpl to AnatolianBlackGoat, the configuration will change, because the configuration is code!
– Integration tests instantiate a fully populated PettingZoo without loading Spring, and without duplicating the logic of how to create one.

public void animalsLikeItWhenIPetThem() {
PettingZoo p = new ZooConfig().pettingZoo();

String result = p.getAnimal().pet();

assertThat(result, is("Maaaaaaaa."));

(Caveat: this isn’t a perfect test. In real life, Spring will proxy the ZooConfig and wrap the goat() call to return one singleton Goat every time. The Spring-created PettingZoo has the same Goat twice. My test PettingZoo has two different Goats.)

This new method of Spring config is a welcome admission that XML is code. If it lives with the code, integrates with the code, and can break the application, then the configuration is code. Pointy braces or curly braces, it’s all code. It might as well be in Java. Putting all this glue and wiring in one place is good, decoupling our application classes is good, and the beautiful part is we can have all this and compile-time type checking too. Mmm, cake.

The phrase “configuration classes” has a lovely ring to it. I hope to hear more of it in the future.

Credit to: St Louis JUG and Chris Hardin of OCI, presenter.