Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am working on a Java project that uses a dependency injection framework built by the company itself. The framework enforces the following naming convention: suppose you have a class Foo that depends on an interface called org.company.IBar:

class Foo {
   @Injection
   private IBar bar;

   ...
}

then the framework will search for a class called org.company.implementation.Bar, create a new instance of that class and then assign it to the attribute Foo.bar. The framework allows for some customization, though. In that @Injection annotation, you can declare your own factory, with which you can enforce your own conventions. But every time you want to use a certain factory, you will have to declare it explicitly in the annotation over the attribute to be injected.

This strategy, however, will make your classes tightly coupled to each other, because when you declare a dependency on an interface, you are already committing to a given implementation. So, I decided to implement my own factory to manually perform dependency injection. It is basically a class that instantiates all application objects and wires them together. Each object has its scope (singleton or prototype) controlled by the factory. Think of a Spring IoC configuration file (but written in Java, instead of XML).

My colleagues did not approve this decision. Their argument is that the factory I created “has too many responsibilities” and the instantiation of each object must be left to the framework. If you need to use another convention, you should create custom factories for each class (as described above). Definitely, according to them, there should not be one single factory where all the objects are instantiated.

I strongly disagree with their argument. The factory has only one responsibility: creating the object graph. Should the need arise to modify that graph, there is only one class that will have to change. But I may be missing something here. What are the pros and cons of each strategy?

share|improve this question
3  
Hate to say it but why not just use Spring or possibly even Guice? You get the benefit that new developers to the team possibly already have experience with Spring and don't need to take time learning a custom framework. –  maple_shaft Oct 20 '11 at 13:25
    
Yes, I would like that, too. But, for political reasons which I'm not at liberty to discuss, the only DI framework allowed for this project is the one I mentioned. –  Otavio Macedo Oct 20 '11 at 13:36

2 Answers 2

up vote 1 down vote accepted

I agree that the model of a single "default" implementation, or one factory per class is too rigid.

I see two potential problems with your approach:

  • wiring up everything in Java makes configuration changes awkward - you need to recompile and redeploy (part of) the app every time,
  • one factory to instantiate the whole object graph may be too coarse grained (depending on the size of the object graph). If the graph is huge, the factory logic becomes hard to maintain. This is why it may be better to have separate factories, although not necessarily one per class. Find a comfortable middle ground, by grouping together closely related / dependent classes.

    Single Responsibility Principle is good to follow, but IMO the main point of it is to create (and keep) classes of manageable size. Note that responsibilities have different levels of abstraction. What may look like a single responsibility on a higher level, is divided into several distinct tasks on a lower level. I can define a "single responsibility" for my class: "satisfy the client's needs" and create a classic God class, which clearly violates the SRP :-)

share|improve this answer
    
Thank you. The second suggestion seems sensible to me and would not be hard to implement. But, regarding the first point, given that my options are either using that framework or no framework at all, I can't see how could I solve it. –  Otavio Macedo Oct 20 '11 at 16:17

Have you looked into using Guice? It is a dependency injection framework like the one you described. However, it allows you to create different injection models that can specify a set of interface to implementation mappings.

public class BillingModule extends AbstractModule {
  @Override 
  protected void configure() {
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);
    bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
    bind(BillingService.class).to(RealBillingService.class);
  }
}

Link to their example implementation.

It seems like a good middle ground between the two options you described. The class objects are getting injected to does not have to explicitly know what class is in charge of doing the injecting. And as the user of the framework, you don't have to do the heavy lifting to ensure that the object graph is instantiated correctly.

share|improve this answer
3  
I guess the OP's company may not be very eager to switch to a 3rd party DI framework though. They may be emotionally attached to their own creation. –  Péter Török Oct 20 '11 at 13:02
    
That's exactly the case, @PéterTörök! –  Otavio Macedo Oct 20 '11 at 13:04
    
@PéterTörök I am emotionally attached to a go-kart that I built with my own two hands, but that doesn't mean that I would use it to drive to work everyday. I also realize that a lot of other people have already created much better go-karts for a lot cheaper than mine. –  maple_shaft Oct 20 '11 at 13:29
    
@maple_shaft, there are several important differences between go-karts and software frameworks, but there is no point going into that. I fundamentally agree with you, alas it's the OP's company that you should convince :-) –  Péter Török Oct 20 '11 at 13:47
    
I'll add that Guice 3.0 is the RI for the Java Standardised DI (JSR-330) - it would be sensible for the company to look at this (or another 330 provider such as Spring) long term. –  Martijn Verburg Oct 20 '11 at 15:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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