I’m working on a kind of parameter values parser library. I’d like to have an Parser defined as 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);
// do other stuff on values
// ...
return valuesMapper.transformValues(values, configuration);
}
}
I’d like this library clients to be unaware of ValuesProvider and ValuesMapper default implementations and use it like
Result result = new Parser(myConfig).parse("sampleParam");
Although there must be possibility to set their own implementations when needed. I wonder how and where should I init those default implementations and still let clients to set their own if they want. I don’t want to stick to
new DefaultValuesProvider()
etc. in constructor, because default implementation would e.g. access filesystem, so that it would be hard to test (mock them out). I know I can use setters (like in DI) but what about defaults?
EDIT:
After your all answer, I guess it is best here to have setters to allow clients to provider their own implementations of ValuesProvider and ValuesMapper. But how to create default implementations? I’d like to decouple instantiation from logic, so I don’t want to use new DefaultValueProvider() here. Is the factory pattern applicable here? If so how and where should I use it?
How about:
As Mark points out, constructor injection might be the better way to go. That would look as follows:
I also agree with his summary of advantages:
However, there are also disadvantages:
My recommendation therefore is to use setter injection, and if it is necessary to prevent the reassignment of dependences, do: