lundi 3 octobre 2022

How to avoid empty visit functions in visitor pattern?

I have the following use case. I have a restriction interface that needs to fill its members from dependencies, do the validations. These methods are applicable for all implementations and hence it is fine till now. Some restrictions require some other validation later. In the main function, I want to loop over each of the restriction and call the methods in a general way instead of using instanceOf and then calling. I think this might be a use case of visitor pattern as mentioned here. Now I have the following classes.

interface Restriction() {
    void fillFields();
    void firstRoundValidation();
    void accept(SecondRoundValidationVisitor secondRoundValidationVisitor);
}
class RestrictionBasic implements Restriction {
    Field field;

    // Inject dependencies

    @Override
    void fillFields() {
        // Get field from dependencies
    }

    void firstRoundValidation() {
        // Implement
    }

    @void accept(SecondRoundValidationVisitor secondRoundValidationVisitor) {
        secondRoundValidationVisitor.visitRestrictionBasic(this);
    }
}
class RestrictionAdvanced implements Restriction {

    // Same as above except below function.

    @void accept(SecondRoundValidationVisitor secondRoundValidationVisitor) {
        secondRoundValidationVisitor.visitRestrictionAdvanced(this);
    }
}
interface ValidationVisitor {
    void visitRestrictionBasic(RestrictionBasic restrictionBasic);
    void visitRestrictionAdvanced(RestrictionAdvanced restrictionAdvanced);
}
class SecondRoundValidationVisitor implements ValidationVisitor {
    @Override
    void visitRestrictionBasic(RestrictionBasic restrictionBasic) {
        // Empty function
    }

    @Override
    void visitRestrictionAdvanced(RestrictionAdvanced restrictionAdvanced) {
        // Perform second level of validation
    }
}
class Main() {
    List<Restriction> restrictionList = new ArrayList();
    ValidationVisitor validationVisitor = new SecondRoundValidationVisitor();
    for (restriction : restrictionList) {
        restriction.accept(validationVisitor)
    }
}

Could you please tell if there is any issue with this approach? There is also another approach where getSecondValidationNeeded() could be added to the interface and based on that, call secondValidation with default value of empty body. But this is not following interface segregation principle. My doubt is how does visitor pattern solve this issue? Even in visitor pattern, there is only one interface and accept is being added in base interface even when only some visitors have non empty visit functions.

Aucun commentaire:

Enregistrer un commentaire