views:

266

answers:

4

I've never been so good at design because there are so many different possibilities and they all have pros and cons and I'm never sure which to go with. Anyway, here's my problem, I have a need for many different loosly related classes to have validation. However, some of these classes will need extra information to do the validation. I want to have a method validate that can be used to validate a Object and I want to determine if an Object is validatable with an interface, say Validatable. The following are the two basic solutions I can have.

interface Validatable {
  public void validate() throws ValidateException;
}
interface Object1Validatable {
  public void validate(Object1Converse converse) throws ValidateException;
}
class Object1 implements Object1Validatable {
  ...
  public void validate() throws ValidateException {
    throw new UnsupportedOperationException();
  }
}
class Object2 implements Validatable {
  ...
  public void validate() throws ValidateException {
    ...
  }
}

This is the first solution whereby I have a general global interface that something that's validatable implements and I could use validate() to validate, but Object1 doesn't support this so it's kind of defunc, but Object2 does support it and so may many other classes.

Alternatively I could have the following which would leave me without a top level interface.

interface Object1Validatable {
  public void validate(Object1Converse converse) throws ValidateException;
}
class Object1 implements Object1Validatable {
  ...
  public void validate(Object1Converse converse) throws ValidateException {
    ...
  }
}
interface Object2Validatable {
  public void validate() throws ValidateException;
}
class Object2 implements Object2Validatable {
  ...
  public void validate() throws ValidateException {
    ...
  }
}

I think the main problem I have is that I'm kind of stuck on the idea of having a top level interface so that I can at least say X or Y Object is validatable.

+2  A: 

what about this :

interface Validatable {
  void validate(Validator v);
}

class Object1 implements Validatable{
  void validate(Validator v){
    v.foo
    v.bar
  }
}
class Object1Converse implements Validator{
 //....
}
class Object2 implements Validatable{
  void validate(Validator v){
    //do whatever you need and ingore validator ? 
  }
}

What do you care if Object2 receives an unneeded argument ? if it is able to operatee correctly without it it can just ignore it right ?

If you are worried about introducing an unneeded dependency between object2 and Object1Converse then simply specify an interface to decouple them and use that as the validator.

Now I must add that having a mixed model where you have both object able to self validate and object which need external state information to validate sounds weird.

care to illustrate ?

Jean
If I was to do it this way then I'd just have validate(Object o) and then each class could determine what type of Object to be passed to it, but then there's no Type checking and effectively anything could be passed to the validate method, which could cause problems.
PintSizedCat
I wouldn't use Object as it conveys no information to a future developper thus I restricted the type to a validator object. I still think there is something wrong with trying to apply a common interface to different behaviors (self and externally validatable).
Jean
Maybe you're right, maybe it's just a case of putting a method on the Class (or an Objects current inherited interface).
PintSizedCat
A: 

Perhaps the apache commons validator project would be useful here - either directly or as a model for how to attack your problem. They effectively have a parallel set of objects that do the validation - so there is no interface on the objects, just the presence/absence of a related validator for the object/class.

Chris Kimpton
I guess the interface here allows him to easily sift through a mixed list of validatable and non validatable objects ...
Jean
Unfortunatley not the type of validation I'm trying to do here, I'll look further into it, it might prove handy, thanks.
PintSizedCat
A: 

This is in C#, but the same ideas can certainly be implemented in many other languages.

public class MyClass {
    //Properties and methods here
}

public class MyClassValidator : IValidator<MyClass> {
    IList<IValidatorError> IValidator.Validate(MyClass obj) {
        //Perform some checks here
    }
}

//...

public void RegisterValidators() {
    Validators.Add<MyClassValidator>();
}

//...

public void PerformSomeLogic() {
    var myobj = new MyClass { };
    //Set some properties, call some methods, etc.
    var v = Validators.Get<MyClass>();
    if(v.GetErrors(myobj).Count() > 0)
        throw new Exception();
    SaveToDatabase(myobj);
}
Justice
A: 

As simple solution to the "can an object be validated" problem is to add a third interface.

This third interface is an empty one that parents both of the others, meaning you can just check against that interface (Assuming you aren't worried about someone spoofing being validate-able), and then iteratively check against the possible validation interfaces if you need to actually validate.

Example:

interface Validateable
{
}

interface EmptyValidateable inherits Validateable //Or is it implements?
{
     void validate() throws ValidateException;
}

interface Objectvalidateable inherits Validateable
{
     void validate(Object validateObj);
}
Guvante