Whilst working on some EDI parsing I have been thinking about data validator attachment.
The classic pattern is to have an AbstractValidator and subclass as necessary. This results in a few more classes in the hierarchy and a lot of objects added unless you implement some sharing or a different approach with delegates.
Consider the case of where I have multiple needs to validate against membership of a code list. Each code list doesn’t deserve its own subclass but what I am more likely to end up with is something like
ret.DefineField "GE01", "Number of Transaction Sets Included", 01, 06, "", _ new ArrayValidator("XX", "YY", "ZZ")
If validators with the same code list are used regularly, we can have them in a property. Assuming validators don’t retain state, there is no reason why they can’t be shared, so the line above would be
ret.DefineField "GE01", "Number of Transaction Sets Included", 01, 06, "", _ mBlahValidator and in the Constructor: mBlahValidator = new ArrayValidator("XX", "YY", "ZZ")
One minor annoyance is where to put classes – do you prefix them with EDI or are they generic enough to put into the main namespace and what if you want to use them again?
A totally different approach which avoids adding any extra classes is to use delegates.
This means a single method per validation scenario is used, which can be as complex in logic as we like and can call any or all of the other validation methods, assuming they are in the same class, without messing around with the Composite pattern.
Delegates obviously come with some runtime overhead but if they are delegating to a Shared (class) method, don’t need to retain an object pointer so are going to be more efficient than individual or shared instances of separate validation objects.
Delegate Function ValidateField(validating as EDIField, value as String) As Boolean