I’ve Struts 1 action class (actions are singletons by design in struts 1) that needs to collect some data and then combine them all into single response.
I’d like to extract all the response generation logic into separate class called
ResponseBuilder
Normally I’d put ResponseBuilder as a field and have setter for it (e.g. for testing).
My response builder looks as follows
class JsonResponseBuilder implements ResponseBuilder {
public void addElement(String key, Object value) {
...
}
public String buildResponse() {
// build response from data collected
}
}
With such implementation I can’t do it due to thread safety issues here.
How can I change this design to be ok? Is Factory pattern here applicable?
I mean is using
ResponseBuilderFactory
as a dependency and calling it that way:
ResponseBuilder builder = factory.getBuilder();
builder.addElement(...);
...
String response = builder.build();
is ok from design and testability point of view?
If it is ok. how to write test code for this? Mock factory? Mock builder?
A factory would work. You’re essentially doing a form of Dependency Injection with a factory. When you instantiate or initialise your action, you would set the factory:
and in the factory, just return a new instance of
JsonResponseBuilderwhen you need it. Make sure that you do not store your instance ofJsonResponseBuilderas an instance variable in your action; it must remain local to the method you’re using, or passed around as a method parameter.As for testing, it becomes easy to replace the factory with a mock factory that returns a mock ResponseBuilder. There are many libraries to do this, like Mockito or JMock. All of them work well with JUnit and TestNG.
Edit:
You’d need to have ResponseBuilderFactory as an interface, like:
When you do your testing, just create a class that returns a mock of your ResponseBuilder:
So you’re not injecting a mock factory, just a factory that returns mocks.
Also, see Dependency Injection vs Factory Pattern.
Edit 2:
If you can somehow manage to re-code your
JsonResponseBuilderso that it doesn’t maintain state, then you could potentially avoid the whole factory mess all together and just use your original approach. Objects that do not maintain state are inherently thread-safe.