Tuesday, June 1, 2010

Dependency Injection and OO

Once upon a time, there was Object-Orientation, and people liked it and wanted to do complex things with it. One idiom that was widely used was dependency injection:
class PaymentCard {
public boolean validateTransaction(Transaction t, Communicator c);
}
Here, a transaction (a different Object) is validated using some communication channel (a different object, being injected). The subclass could then just say

class VisaCard extends PaymentCard {
public boolean validateTransaction(Transaction t, Communicator c) {
super.validateTransaction(t, new VisaCommunicator());
}
}
Alas, the real world is not that easy. The VisaCommunicator is probably something that needs to be injected into VisaCard, or else it needs other injections like SerialCommunicator, EthernetCommunicator, RandomGenerator, CertificateHandler and whatnot. Pretty soon, the methods become huge.

"This is a bother", says everybody, and proceeds to move the injections into the constructor. However, it still means that to construct an object, you need to know what it and all objects it constructs needs injected.

"This breaks encapsulation", says everybody, and proceeds to make Dependency Injection frameworks where all these things are done automagically with annotations, reflections and all manner of other niftiness. Now several layers of reflection, lookup and wrapping is done for each object creation.

"This is slow", says everybody, and proceed to move the injection into "beans" that handle various layers of services: web service layer, business service layer, data access objects, ... The injections can now be done only when a new bean is needed, and since beans are stateless, they can be pooled and reused. Much faster. Scales nicely.

"This is not object-oriented", says I. My objects no longer have any significant functionality on them, since anything that requires injections (which turns out to be many things) must live in the beans. Code becomes spaghetti once again. However, these injections are almost all "static" injections - the objects injected are always the same class and have no state. So maybe each "OO class" (class that is actually object-oriented) could have an associated class that just holds its injections? It cannot be a static field, as they don't play well with beans. It should just be findable at construction time to be plugged into the object. Surely somebody has done this, I says, and wander off looking for a solution