Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is a somewhat difficult question to answer, especially because it's a contrived example, but if we assume that your classes are already designed exactly as you want them, the correct application of dependency injection here is simple. You seem to be focused on the testability of your StringValidator and on trying to do something magic to it with dependency injection. Where you <em>should</em> be concerned about testability is in your Main class. That's where you've introduced tight coupling and untestable code, and it's where a DI container will show its value. Proper application of DI and IoC principles might result in something like this instead:</p> <pre><code>public class Main { @Autowired private Validateable validateable; @Autowired private Stringable stringable; public void main() { final List&lt;String&gt; validationList = validateable.getValidationList(); final List&lt;String&gt; stringList = stringable.getStringList(); StringValidator stringValidator = new StringValidator(stringList, validationList); stringValidator.validate(); final List&lt;String&gt; validatedList = stringValidator.getValidatedList(); } public static void main(String[] args) { Container container = new ...; container.get(Main.class).main(); } } </code></pre> <p>In other words, all of your manual wiring just gets turned over to the control of the DI container. That's the whole point. Personally, I wouldn't be happy with this because you still have something that looks like a "component" class--the StringValidator--being instantiated by your code. I would look at ways to redesign things to get rid of this hard dependency in your code and turn that creation over to the container as well.</p> <p>As for this "new new", no, DI containers aren't new. They've been around for quite a while. If you mean, "Should I use one?", then I guess my answer would be generally "yes", though the pattern is more important than any particular implementation. The benefits are well established and accepted, and it's more a way of thinking than an actual framework. As I've just demonstrated, your Main class was in essence a primitive DI container.</p> <p><strong>Update:</strong> If your primary concern is how to deal with the inputs to your StringValidator, there are a couple of options. There's no reason your "stringList" and "validationList" can't be managed by a DI container and injected into your StringValidator. Then the source of those lists is up to the container. They could come from your other objects or be injected by a test. Alternately, maybe you're looking to change the abstraction around how your StringValidator gets its inputs? In that case, maybe something like this will better suit your needs:</p> <pre><code>public class StringValidator { private SourceOfStrings stringSource; private SourceOfStrings validationStringSource; private final List&lt;String&gt; validatedList = new ArrayList&lt;String&gt;(); ... public void validate() { for (String currentString : stringSource.getStrings()) { for (String currentValidation : validationStringSource.getStrings()) { if (currentString.equalsIgnoreCase(currentValidation)) { validatedList.add(currentString); } } } } public List&lt;String&gt; getValidatedList() { return validatedList; } } interface SourceOfStrings { List&lt;String&gt; getStrings(); } </code></pre> <p>Note: <em>NOT</em> thread-safe. In a threaded environment, I would definitely go an extra step to remove the need to store the result in a field and call an extra method call to get it.</p>
 

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