How do I reduce number of factory classes in my factory pattern implementation that Validates fields?

  softwareengineering

I am trying to write RSQL Parser which checks if the RSQL is logically correct.
while the RSQL Java library checks whether the RSQL expression is grammatically correct, it doesn’t check if the expression is logically correct.

One example of logically incorrect expressions would employee.name > 10 as the name is of String type, users should not be able to use >, <, >=, <=

Now to write this logic I am using a factory pattern as below:

public interface FieldValidator {
   public boolean isValidExpression(ComparisonNode comparisonNode);
}

public class NameFieldValidator implements FieldValidator {
   public Set<ComparisonOperator> supportedOperators = Set.of(EQUALS, NOT_EQUALS, IN, NOT_IN);

   public boolean isValidExpression(ComparisonNode comparisonNode) {
       ComparsionOperator operator = comparisonNode.getOperator();
       if(!supportedOperators.contains(operator)) {
          return false;
       }
       // other rules
   }

}

Then I create a factory using FieldValidator implementations and call factory implementation based on the i/p field.

But the problem I am facing here is that I have around 40 fields in my data model and might end up creating 40 implementations here.

Am I over-engineering here? is this not a good use case for a factory pattern? any other design that I should explore?

One should be comparing by type, not by field. One can take a fail-fast approach or try and make a comparison via an under the hood conversion.

Comparing…

Apple > Orange

Doesn’t make that much sense.

Apple > “Apple” where “Apple” is a converted Orange.

I convert my orange into an apple. ==> “Name” > “10”

Now I can get an answer.

So, one can check to make sure the same things are being compared and if not throw an exception right away (fail-fast). Or one can make a best effort to always return an answer.

The first way should be less code. The second way needs to take in a lot of scenarios and may return “non-sensical” answers unless specifics are known about the conversion process and language being used.

With this approach, one should have a few classes of comparators. For example, comparators can include ==> String, Number, Boolean, etc. Take the data point on the left and instantiate a comparator by its type and do the comparison. If the right type doesn’t match, fail or try convert it to the type of the left. Each comparator can have a list of supported operators based off that type. If the operator isn’t supported for that particular type throw an exception.

1

LEAVE A COMMENT