java - configurable dependencies with easy to mock out default implementations -


i'm working on kind of parameter values parser library. i'd have parser defined follows:

public class parser {      private valuesconfiguration configuration;     private valuesprovider valuesprovider;     private valuesmapper valuesmapper;      public parser(valuesconfiguration configuration) {         this.configuration = configuration;     }      public result parse(string parametername) {         list<values> values = valuesprovider.getvalues(parametername);         // other stuff on values         // ...         return valuesmapper.transformvalues(values, configuration);     } } 

i'd library clients unaware of valuesprovider , valuesmapper default implementations , use like

result result = new parser(myconfig).parse("sampleparam"); 

although there must possibility set own implementations when needed. wonder how , should init default implementations , still let clients set own if want. don't want stick

new defaultvaluesprovider() 

etc. in constructor, because default implementation e.g. access filesystem, hard test (mock them out). know can use setters (like in di) defaults?

edit: after answer, guess best here have setters allow clients provider own implementations of valuesprovider , valuesmapper. how create default implementations? i'd decouple instantiation logic, don't want use new defaultvalueprovider() here. factory pattern applicable here? if how , should use it?

how about:

public void setvaluesprovider(valuesprovider valuesprovider) {     this.valuesprovider = valuesprovider; }  public result parse(string parametername) {     if (valuesprovider == null) {         valuesprovider = new defaultvaluesprovider();     }      list<values> values = valuesprovider.getvalues(parametername);     // other stuff on values     // ...     return valuesmapper.transformvalues(values, configuration); } 

as mark points out, constructor injection might better way go. follows:

public parser(valuesconfiguration configuration) {     this(configuation, new defaultvaluesprovider()); }  public parser(valuesconfiguration configuration, valuesprovider valuesprovider) {     this.configuration = configuration;     this.valuesprovider = valuesprovider; }   public result parse(string parametername) {     list<values> values = valuesprovider.getvalues(parametername);     // other stuff on values     // ...     return valuesmapper.transformvalues(values, configuration); } 

i agree summary of advantages:

this enable make dependency final/readonly. property injection provides quite weak guarantees invariants - e.g. keep changing dependency on same instance, , that's not want.

however, there disadvantages:

  1. the number of constructors exponential in number of optional parameters, causing lot of delegation , duplicated javadoc parameters. therefore, i'd use constructor injection if there few optional dependencies. have 2, pain threshold kind of thing.
  2. constructor injection ist not subclassing friendly, subclass constructors have redeclare super class dependencies. in case, subclass wishes expose configuration options need 4 constructors ... , if adds optional parameter better shouldn't constructor injection, require 4 constructors.

my recommendation therefore use setter injection, , if necessary prevent reassignment of dependences, do:

public void setvaluesprovider(valuesprovider valuesprovider) {     if (this.valuesprovider != null) {         throw new illegalstateexception("dependency set");     }     this.valuesprovider = valuesprovider; } 

Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -