Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design question - java - what is the best way to doing this?

Tags:

java

oop

I have a design problem.

I have two data objects which are instances of say class A and class B. A and B don't have any behavior - they are java beans with getters and setters. I have a Validation interface and 10 implementations of it defining different Validations. I would like to specify in my properties file which Validation applies to which class. Something like this:

class A XYZValidation,ABCValidation

class B: ABCValidation, PPPValidation, etc

How do I write my Validation class so that it serves objects that are instances of Class A OR ClassB, or just about any other Class C that I might want to add in future?

interface Validation {
public boolean check(??);
}

> Just wanted to add this line to say thank you to all those who have responded to this post and to say that I am loving my time here on this amazing website. Stackoverflow rocks!

like image 795
Jay Avatar asked Jun 05 '09 07:06

Jay


People also ask

What is Java system design?

System Design is the process of designing the architecture, components, and interfaces for a system so that it meets the end-user requirements.


3 Answers

I've probably misunderstood the question but would something like this suffice:

public class ValidationMappings {
    private Map<Class, Class<Validation>[]> mappings = new HashMap<Class, Class<Validation>[]>();

    public ValidationMappings() {
            mappings.put(A.class, new Class[]{XYZValidation.class, ABCValidation.class});
            mappings.put(B.class, new Class[]{ABCValidation.class, PPPValidation.class});
    }

    public Class[] getValidators(Class cls) {
            if (!mappings.containsKey(cls)) return new Class[]{};
            return mappings.get(cls);
    }
}

When you want to get the list of validators for a particular class, you would then call getValidators(Class cls) and iterate over each validator and create an instance of each and call your check method.

like image 36
digiarnie Avatar answered Oct 27 '22 20:10

digiarnie


Have you thought about using annotations to mark the fields you want to validate in your bean?

If you have 10 different validations you could specify 10 annotations. Then mark the fields using annotations:

@ValideStringIsCapitalCase
private String myString;

@ValidateIsNegative
private int myInt;

With reflection API iterate through all the fields and see if they are marked, something like this:

public static <T> validateBean(T myBean) throws IllegalAccessException {
    Field[] fields = myBean.getClass().getDeclaredFields();
    // This does not take fields of superclass into account
    if (fields != null) {
        for (Field field : allFields) {
            if (field.isAnnotationPresent(ValideStringIsCapitalCase.class)) {
                field.setAccessible(true);
                Object value = field.get(existingEntity);
                // Validate
                field.setAccessible(false);
            }
        }
    }
}

An option would be to mark the whole class with the validator you want to use.

EDIT: remember to include annotation:

@Retention(RetentionPolicy.RUNTIME)

for your annotation interface.

EDIT2: please don't modify the fields directly (as in the example above). Instead access their getters and setters using reflection.

like image 159
tputkonen Avatar answered Oct 27 '22 19:10

tputkonen


something like this maybe?

interface Validation {
   public boolean check(Validatable x);
}

interface Validatable {
}


class A implements Validatable {
  ...
}

class Validator {
   public boolean validateObject(Validatable x){
      boolean validated = true;
      ... //read config file, check which validation classes to call
      //for each validation class v in the config file:
          if(!v.check(x)) validated = false;
      return validated;
   }
}
like image 32
Fortega Avatar answered Oct 27 '22 18:10

Fortega