Note that there are some explanatory texts on larger screens.

plurals
  1. PODependency injection, delayed injection praxis
    primarykey
    data
    text
    <p>A simple(and lengthy) question, and not a simple answer. Working with some DI frameworks(Spring, Guice) I came to a conclusion that some of the praxis presented by others is not so simple to implement. I really seem stuck on this level.</p> <p>I will try to present this as simple as possible, even though some of the details will probably be lost. I hope the question will be clear.</p> <p>Say I have a StringValidator, a simple class with a responsibility to validate strings.</p> <pre><code>package test; import java.util.ArrayList; import java.util.List; public class StringValidator { private final List&lt;String&gt; stringList; private final List&lt;String&gt; validationList; private final List&lt;String&gt; validatedList = new ArrayList&lt;String&gt;(); public StringValidator(final List&lt;String&gt; stringList, final List&lt;String&gt; validationList) { this.stringList = stringList; this.validationList = validationList; } public void validate() { for (String currentString : stringList) { for (String currentValidation : validationList) { if (currentString.equalsIgnoreCase(currentValidation)) { validatedList.add(currentString); } } } } public List&lt;String&gt; getValidatedList() { return validatedList; } } </code></pre> <p>The dependency is the lowest possible, allowing simple tests like these:</p> <pre><code>package test; import org.junit.Assert; import org.junit.Test; import java.util.ArrayList; import java.util.List; public class StringValidatorTest { @Test public void testValidate() throws Exception { //Before List&lt;String&gt; stringList = new ArrayList&lt;String&gt;(); stringList.add("FILE1.txt"); stringList.add("FILE2.txt"); final List&lt;String&gt; validationList = new ArrayList&lt;String&gt;(); validationList.add("FILE1.txt"); validationList.add("FILE20.txt"); final StringValidator stringValidator = new StringValidator(stringList, validationList); //When stringValidator.validate(); //Then Assert.assertEquals(1, stringValidator.getValidatedList().size()); Assert.assertEquals("FILE1.txt", stringValidator.getValidatedList().get(0)); } } </code></pre> <p>If we wanted to increase the flexibility even more, we could use Collection&lt;> instead of List&lt;>, but let's presume that that won't be necessary.</p> <p>The classes that create the lists are the following(use any other interface standard):</p> <pre><code>package test; import java.util.List; public interface Stringable { List&lt;String&gt; getStringList(); } package test; import java.util.ArrayList; import java.util.List; public class StringService implements Stringable { private List&lt;String&gt; stringList = new ArrayList&lt;String&gt;(); public StringService() { createList(); } //Simplified private void createList() { stringList.add("FILE1.txt"); stringList.add("FILE1.dat"); stringList.add("FILE1.pdf"); stringList.add("FILE1.rdf"); } @Override public List&lt;String&gt; getStringList() { return stringList; } } </code></pre> <p>And:</p> <pre><code>package test; import java.util.List; public interface Validateable { List&lt;String&gt; getValidationList(); } package test; import java.util.ArrayList; import java.util.List; public class ValidationService implements Validateable { private final List&lt;String&gt; validationList = new ArrayList&lt;String&gt;(); public ValidationService() { createList(); } //Simplified... private void createList() { validationList.add("FILE1.txt"); validationList.add("FILE2.txt"); validationList.add("FILE3.txt"); validationList.add("FILE4.txt"); } @Override public List&lt;String&gt; getValidationList() { return validationList; } } </code></pre> <p>And we have a Main class with a main method:</p> <pre><code>package test; import java.util.List; public class Main { public static void main(String[] args) { Validateable validateable = new ValidationService(); final List&lt;String&gt; validationList = validateable.getValidationList(); Stringable stringable = new StringService(); final List&lt;String&gt; stringList = stringable.getStringList(); //DI StringValidator stringValidator = new StringValidator(stringList, validationList); stringValidator.validate(); //Result list final List&lt;String&gt; validatedList = stringValidator.getValidatedList(); } } </code></pre> <p>So let's say that the classes generate the lists in runtime(when the user wants to). The "direct"(static) binding is impossible. </p> <p>If we want to provide the lowest possible coupling, we would use the lists to provide us with data required to run the validation(StringValidator).</p> <p>BUT, if we want to use the container to help us with the "glue code", we could inject the two "services" into the StringValidator. That would provide us with the correct data, but at the cost of COUPLING. Also, StringValidator would have the extra responsibility of actually calling the dependencies.</p> <p>If I use delegation in that way, I clutter my code with unwanted responsibilites(not something I want).</p> <p>If I don't, I don't see a way in wich this could work(Provider could provide me with the correct lists, but, again, the dependency is there).</p> <p><strong>The more generic question is - is there a way to actually create a completly decoupled application using DI frameworks, or is this some sort of an ideal? In wich situations do you use the DI framework, in wich you don't? Are DI frameworks really the "new new"?</strong></p> <p>Thank you.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload