When using the factory pattern, should the factory itsel contain validation logic or should that be left up to the calling classes to take care of validation before passing the context data in?
I have a simple factory method but it relies on a config tree being passed to it to decide what object to instantiate.
There could be a situation where the config xml might be well formed, but not in the correct format the factory is expecting and I dont know where this should be validated.
When using the factory pattern, should the factory itsel contain validation logic or should that be left up to the calling classes to take care of validation before passing the context data in?
There are two distinct alternatives to organize validation:
There is a separate validation method Validate(Config)
. This method is called before construction method and returns information whether Config
is valid or not. If Validate
method returns that Config
is valid, then construction method is called. Any error during construction process is considered to be an exception.
There is no separate validation method. Instead validation happens inside construction method when needed. Construction method is allowed to fail and to return either a constructed object or a result indicating an error.
The second variant can be nicely implemented using monads with almost zero code and performance overhead.
What do you mean by validation? And what makes you think code that is part of an instance of the Factory design pattern is different from any other code?
If by validation you mean checking of input values read from the user or an input file, the answer is no: the code for parsing the input is responsible for validation, not a Factory that subsequently uses the read values.
If by validation you mean having the factory methods of the Factory checking that their callers have supplied values that conform to the preconditions of those methods, the answer is the same as for any other method that imposes preconditions on its arguments: the consensus style for Java is for methods to check their preconditions and to throw a suitable RuntimeException
if the preconditions are not met.
Now, in practice, this means some input values will be checked twice. First by the input validation code, and then by the precondition checks of the Factory. Partly that is the cost of breaking code into modules (here, a separate input module and service layer).
But it it also allows the checks to report in different ways, which are more appropriate for their purposes.
Why not offer both? With this, you pass the responsibility to the caller as to whether he wants his input validated or not.
Take this example from Apache Commons - InstantiateFactory
:
Its default constructors offer no validation:
InstantiateFactory(java.lang.Class classToInstantiate)
Constructor that performs no validation.
But offers validation in getInstance
:
static Factory getInstance(java.lang.Class classToInstantiate, java.lang.Class[] paramTypes, java.lang.Object[] args)
Factory method that performs validation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With