DI/IoC helps testing because you can decide, easily, what implementation to use, without modifying the code that uses it. This means you can inject a known implementation to exercise specific functionality, e.g. , simulate a web service failure, guarantee good (or bad) input to a function, etc.
DI/IoC helps testing because you can decide, easily, what implementation to use, without modifying the code that uses it. This means you can inject a known implementation to exercise specific functionality, e.g. , simulate a web service failure, guarantee good (or bad) input to a function, etc.Factories are not required to make DI/IoC work. Whether or not a factory is required depends entirely on usage specifics.
Public class Fizz { @Inject // Guice, new JEE, etc.Or @Autowired // Spring, or private Widget widget; public void doSomething() { int foo = widget. CalculatePremable(this. RippleFactor); doSomethingElse(foo); } }.
Thanks! Any chance you could modify your answer to indicate if I've set up DI correctly, and/or show me an example of how to write Fizz::doSomething() without the need for a WidgetFactory? – Adam Tannon Dec 20 at 16:01 @AdamTannon Done.
– Dave Newton Dec 20 at 16:11 And what if I need different Widgets inside different Fizz methods? I assume in that case that an injected WidgetFactory is appropriate? – Adam Tannon Dec 20 at 16:14 @AdamTannon Possibly, although without knowing the actual usecase it's hard to say.
– Dave Newton Dec 20 at 16:16.
I think the answer to this question, at its core, is simple : The benefits of Dependency Injection can be realized using normal java, but at the cost of adding lots of boiler plate. DI allows you to decouple and modularize your classes without necessarily adding a bunch of parameterized constructors / Factory methods, etc to your source code base.
In your Fizz example class, it's a DI anti-pattern to make an explicit call into the DI framework to get the bean you want. The whole point of DI is the Hollywood principle (don't call us, we'll call you). So your DI framework should be injecting a Widget into Fizz.
When it comes to testing, my preference is the test fixture creates a stub or mock of the dependency. Or the real thing when it's appropriate. The test fixture injects the stub using the same constructor or setter method that, in production, would be used by my DI framework.
Some people like to run tests inside their DI container, but I don't see the point in this for unit tests - it just creates an extra lot of configuration to maintain. (For integration tests it's worthwhile, but you should still have as much of your DI context as possible in common between the production and integration-test contexts. ) The conclusion of all that is that I don't see a whole lot of use to the Factory pattern.
Can you give us a link to the article(s) you've been reading? I'll see if I can dig up one or two myself. Edit: Here's the promised link: Is Dependency Injection Replacing the Factory Patterns?
, one in a series of rather good articles about DI.
If thats the case, then I would need to create instance variables for every single class used throughout every Fizz method...something doesn't feel right there. I could end up with Fizz having 30 instance variables! – Adam Tannon Dec 20 at 16:04 DI is not a replacement for factories; they solve different problems--in the section labeled "how does DI solve this" in your linked article there's still an object factory (and is explicitly called as much).
DI can solve some uses of factories. – Dave Newton Dec 20 at 16:06 1 @AdamTannon - If you keep your classes small and dedicated to specific purposes you will not have the problem of an excessive number of instance variables. – David V Dec 20 at 16:07 @AdamTannon The whole point of DI is to let a container do the lifting for you.
But yes, ideally, in a loosely-coupled system, instance variables would be injected, relieving the class of instantiation responsibilities. – Dave Newton Dec 20 at 16:08 1 @AdamTannon If you want to inject it in the usual DI manner, yes. Though if Fizz is using 30 other classes, it probably has too many responsibilities and needs breaking up.
– Andrew Spencer Dec 20 at 16:08.
Dependency injection definitely makes code more testable. When I come to untested EJB3 code that used the Dependency injection, it is like night and day compared to getting other types of legacy code under test. As for factories, they can have two roles.
One is dependency injection when you don't have a dependency injection framework. This is a static factory pattern, spoken about in effective Java, which is actually rather unique to Java, and best done for other reasons (elaborated there). You see some of that in the JDK, and it is a bear for testing, and certainly doesn't make testable code naturally, as it is something you have to be very conscious about using.
Another role for factories, where you are using the Gang of Four true pattern, in dependency injection is where the construction of the actual object is somewhat involved, not a simple constructor. In that case, you inject a factory, which can be represented in a simple interface, and then have the factory implementation do the heavy lifting. This is more built around the principle of in programming, there is no problem that cannot be solved with yet another layer of indirection.It actually wasn't until I started doing Guice dependency injection that I found a need for the GOF factory pattern in Java.
DI enables you to program to interfaces without having to use factories. Programming to interfaces and the ability to pass in a concrete implementation form outside of the class is what makes code easier to test. Interface Widget { } class UserOfWidget { Widget widget; public UserOfWidget(Widget widget) { this.
Widget = widget } } Using spring dependency injection In a test case UserOfWidget uow = new UserOfWidget(new StubWidget()); Without DI to achieve the same you would need to hide the creation of the concrete Widget behind a factory - similar to the messy code that you have in your example. That said there is a case for using Factories even when you are using DI. Mostly for scenarios where the construction of the object is complex - requires multiple steps, cannot be done by just a simple constructor call.
One such example is retrieving an object from JNDI (a datasource for example). All the logic to lookup the object from JNDI is encapsulated in an factory - which then can be configured as a simple bean in the XML file. To summarize - you don't need factories with DI to make code more testable.
Just DI is enough. Factories are only required to simplify creation of objects that are complex to create.
You have a factory, but you are not using Dependency Injection in your Fizz class. That is why you are not having an easy time testing it. You need to inject either the applicationContext or the WidgetFactory directly.
I prefer the latter in most cases. Public class Fizz { private WidgetFactory wf; public Fizz(WidgetFactory widgetFactory) { wf = widgetFactory; } public void doSomething() { Widget widget = wf.getWidget(); int foo = widget. CalculatePremable(this.
RippleFactor); doSomethingElse(foo); } } Now that you have this, you can inject mock objects into your Fizz class. In the example below I use Mockito, but you can use other mocking frameworks (or make your own mock, if you really want). @Test public void test() { WidgetFactory wf = mock(WidgetFactory.
Class); // mock is a Mockito function that creates mocks for you automatically. Fizz objectUnderTest = new Fizz(wf); // Test Fizz } In your unit testing you really don't want to load an applicationContext. That is why you mock it in code and then pass it in directly.
Thus you will have only one simple applicationContext and that for production. In regard to you question about needing a factory for everything, no you don't need a factory for everything. For objects which my class uses and does not create, I prefer to use DI and pass it in through a constructor.
You can also pass it in through a setter if it is optional. If the class does create a new object then a factory may be appropriate. As you begin to learn how to use DI, factories, and write testable code I think you will be able to get a feel for when it is too much to write a factory or not.
David - thanks for your very thorough answer and helpful code samples! You've helped me take the next step in comprehending this stuff. I do have the same question for you as I had for @Andrew Spencer: This arrangement forces me to add an instance variable to Fizz's design for every object I want to inject into it.So, this means that if Fizz has 10 methods, and inside each of those 10 methods are a total of, say, 15 different objects (defined elsewhere in other packages), then I need to have 15 instance variables for each of them!
Is this correct or am I missing something?!? – Adam Tannon Dec 20 at 16:11 1 Yes, and if you have 15 dependencies in your class than that's something you want to think about - does it really need all these things to do it's job? Whenever I see a class with more than a few injected services I try and figure out a way to refactor – Bedwyr Humphreys Dec 20 at 16:15 1 @AdamTannon - I mentioned in the comments in Andres Spencer's post that you will not have this problem if you make your classes small and give them more specific purposes.
Small classes with limited purposes are more reusable and easier to test anyway, so I encourage it in general. You could refactor Fizz, or you could try to apply DI (with or without a factory) on a smaller class first. That will help you to better understand the concepts.
– David V Dec 20 at 16:16.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.