2

I have class Validator, which manage all validation criteria from files and database. But this criteria are loaded by Loader like this:

Validator validator = Loader.load("clients"); //get all from clients.cfg file

What is the best approach to determine from another class, which criteria are currently loaded?

Importer importer;
Validator clientsValidator = Loader.load("clients");
Validator addressValidator = Loader.load("address"); ...
importer.validate(data, clientsValidator, addressValidator);

public class Importer{
   public void validate(Data data, Validator... validator){
      ...
      validateClient(data, one of validators);
      validateAddress(data, another of validator);
      ...
   }
}

I need to know in Importer class, which Validator is for Clients, which for Addresses... Any good approaches?

3 Answers3

1

The best way would be for you to be add a field and accompanying method to Validator to return the identifier (e.g. "clients") with which it was created.

Alternatively, if by using a different identifier when calling Loader.load() you get back instances of different classes implementing the Validator interface, then you can use the Object.getClass() method to tell those classes apart. If those classes are within a pretty small set you might even get away with using instanceof directly.

We would need more information, such as what Loader does exactly, what Validator is and how much you are allowed to change their code before being able to provide a more concrete answer.

EDIT:

Quite honestly, perhaps you should reconsider a redesign of your data model. As it stands, you can apparently mix clients and addresses without any checks. You should restructure your code to be able to rely on the type safety features of Java.

One way would be to have a generic class/interface Validator<T>, where T would the class of the validated objects:

public interface Validator<T> {
    public boolean validate(T object);
}

You could then have specific Data subclasses for your data, such as Address or Client, and set typed Validator objects to Importer through specific methods:

public class Importer {
    public void addAddressValidator(Validator<Address> validator) {
        ...
    }

    public void addClientValidator(Validator<Client> validator) {
        ...
    }
}

This is far safer than mixing all validator objects in a single variadic method call, and it is also the preferred approach of most common frameworks in the wild.

thkala
  • 84,049
  • 23
  • 157
  • 201
0

Why not have a getSource() in Validator which gets set when Loader loads the source.

Thinking more about the specific question below :

I need to know in Importer class, which Validator is for Clients, which for Addresses... Any good approaches?

Actually a better way to do this is if Loader can return a ClientValidator (implementation of Validator) for client and AddressValidator for addresses.
That way you can avoid the if-else conditions and directly call validate on the Validator class

Ajay George
  • 11,759
  • 1
  • 40
  • 48
0

Pass the validators by position. You must also check if the specific validator is null or not before you use.

public void validate(Data data, 
    Validator clientsValidator, 
    Validator addressValidator) {
    ...
    if (clientsValidator != null) {
        validateClient(data, clientsValidator);
    }
    if (addressValidator != null) {
        validateAddress(data, addressValidator);
    }
    ...
}
gaborsch
  • 15,408
  • 6
  • 37
  • 48