Page 1 of 1

Inheritance vs composition in form validation

Posted: Sat Mar 04, 2006 2:32 pm
by matthijs
Recently we had a very interesting thread about form validation.

Many gave their ideas about strategies for form validation. I had learned myself about the strategy pattern as explained on PHPpatterns. As a response Arborint gave some code, based on a Rules bases Validator class approach.
arborint wrote:It is an interesting study in the change that has happened in the last few years from using inheritence (like the article uses) to composition
To me Feyd seemed positive about such an approach:
feyd wrote:Personally, I prefer a class for each rule. With a unified interface, rules are entirely interchangable. Which has amazing power potential and VERY easy to extend/customize
Now I have experimented with both approaches: the Strategy pattern of phppatterns using inheritance and the Rules based aproach of Arborint.

Some parts of the code:
Inheritance:

Code: Select all

class ValidateEmail extends Validator {
    /**
    * Private
    * $email the email address to validate
    */
    var $email;

    //! A constructor.
    /**
    * Constucts a new ValidateEmail object subclass or Validator
    * @param $email the string to validate
    */
    function ValidateEmail ($email){
        $this->email=$email;
        Validator::Validator();
    }

    //! A manipulator
    /**
    * Validates an email address
    * @return void
    */
    function validate() {
        $pattern=
    "/^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/";
        if(!preg_match($pattern,$this->email)){
            $this->setError('Invalid email address');
        }
        if (strlen($this->email)>100){
            $this->setError('Address is too long');
        }
    }
}
Composition:

Code: Select all

class RuleEmail extends Rule {

    function RuleEmail($field, $errorMsg) {
      $this->field    = $field;
      $this->errorMsg = $errorMsg;
    }

    function isValid($request) {
      $user      = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\.|\{\}~\']+';
      $doIsValid = '(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]\.?)+';
      $ipv4      = '[0-9]{1,3}(\.[0-9]{1,3}){3}';
      $ipv6      = '[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7}';

      return (preg_match("/^$user@($doIsValid|(\[($ipv4|$ipv6)\]))$/", $request[$this->field]));
    }
} // end class RuleEmail
I have read about inheritance and composition. But I don't understand yet what advantages or disadvantages they have in this situation. Could anyone shed some light on this? Or point me in the right direction?

From a practical point of view, I would prefer the usage of the second method

Code: Select all

$validator->addRule(new RuleEmail('email', 'This is not a valid email address'));
over the first

Code: Select all

$v['e']=new ValidateEmail($_POST['email']);
as the Rules method allows me to set the error messages in the View instead of in the class.

Thanks!

Posted: Sat Mar 04, 2006 7:54 pm
by timvw
If you opt for composition, you are saying: I need Validator.. And i it can use the help of a RegexValidator, EmailValidator and a CreditcardValidator.

If you opt for inheritance, you are saying: I need a Validator.. And it can do Regex validation, Email validation and Creditcard validation...


To me it seems that you need a bit of both ;) It seems obvious (to me) that you want to Validate things. So each validator should look like:

Code: Select all

<?php
interface Validator {
  // returns true if the value is valid, false otherwise
  public function IsValid($value);
}
?>
Then you would implement this interface a couple of times to write a RegexValidator, EmailValidator, ... (In some way you're extending/inheriting from the base Validator class/interface)

Now, when you are using a form you usually need more than one Validator. Eg: you need a RegexValidator to check some serialnumber and an EmailValidator to check the submitted e-mail. So if you want to write a validator for your form you'll probably want to compose a class that has a couple of validators.

Code: Select all

<?php
class FormValidator {
  public AddValidator($inputfield, $validator);
}
?>
And you use it like:

Code: Select all

<?php
$v1 = new EmailValidator();
$v2 = new CreditcardValidator();

$vf = new FormValidator();
$vf->AddValidator("e-mail", $v1);
$vf->AddValidator("creditcard", $v2);
?>
(It appears that the code that arborint provided in that other thread does exactly the same...)

Posted: Sun Mar 05, 2006 1:43 am
by matthijs
Tim, thanks for your reply.
If you opt for composition, you are saying: I need Validator.. And i it can use the help of a RegexValidator, EmailValidator and a CreditcardValidator.

If you opt for inheritance, you are saying: I need a Validator.. And it can do Regex validation, Email validation and Creditcard validation...
It's this subtle (?) difference what I was talking about. And which is still a bit hard to comprehend the consequences of.
To me it seems that you need a bit of both
Yes, I think so. A class which composes another one inheritates methods from the first, so although the 2 are different things they share some aspects as well, right?
It appears that the code that arborint provided in that other thread does exactly the same
From what I can see they are indeed about the same, only implemented a bit differently. But it's nice to see your examples. I learn a thing with each example I see and each explanation I read.

But to go back to my question: would you say one method is better (in some situations) then the other? I see now that both methods are quite alike in how they function and are implemented, but I ask this because of what Arborint said:
It is an interesting study in the change that has happened in the last few years from using inheritence (like the article uses) to composition
which seems to mean to me that using composition has some advantage.

Well, maybe I'm still missing something, I'll go and study some more oop basics. Everybody here is probably very busy checking out the zend framework :)

Posted: Sun Mar 05, 2006 6:26 am
by timvw
matthijs wrote: But to go back to my question: would you say one method is better (in some situations) then the other? I see now that both methods are quite alike in how they function and are implemented, but I ask this because of what Arborint said:
It is an interesting study in the change that has happened in the last few years from using inheritence (like the article uses) to composition
which seems to mean to me that using composition has some advantage.
Only experience can teach how to choose the most appropriate.. I'll try to generalise my example a bit: Do you want to change the behaviour of a class? If yes, then inherit from the class and change the functions you want to behave different. If no, then you can compose a new (collection of) object(s) that use(s) object(s) to do the validation..

My guess is that most people only get to see examples of inheritance when they are learning about OOP. And that could explain why the choice for inheritance seems more appropriate to them in the beginning... After a while they get more experience and evolve towards better design decisions...

A harder example would be the following: We want to validate creditcardnumbers and we already have a RegexValidator.
When you feel that a CreditcardValidator is a sort of RegexValidator the most appropriate way would be to extend the RegexValidator and change the Validate method... If you feel that a CreditcardValidator isn't a sort of RegexValidator but it could use one to help in the validation (has a) then you should opt for composition...

Which one is better? Hard to tell at first sight..

Imagine that the RegexValidator has a setter method to change the used regex... Would you really want to have a CreditcardValidator that allows the user to change the used regex? So you probably want to change the behaviour of the RegexValidator...

Posted: Sun Mar 05, 2006 7:35 am
by matthijs
Wow, thanks again for your elaborate response. Not easy for me but very good material.
Imagine that the RegexValidator has a setter method to change the used regex... Would you really want to have a CreditcardValidator that allows the user to change the used regex?
I don't think so.
So you probably want to change the behaviour of the RegexValidator...
So that means I can better use composition then inheritance in this case, isn't it? The CreditCardValidatorClass should compose the RegexValidator.