Checking Integers with the Strategy Design Pattern

If you’re a PHP developer who wants to learn how to implement the Strategy design pattern in a real-world project, then you might want to take a look at this article series. Over the course of its six tutorials, you’ll walk through the development of a modular and flexible application, which will use this powerful pattern to validate different types of data, including integer and float numbers, email addresses and URLs.

And now that you’ve been introduced to the subject covered by this series, it’s time to review the topics covered in the first tutorial, in case you haven’t read it yet. In that part I explained in depth the logic that stands behind the Strategy pattern, as well as how to use it for checking the validity of incoming data at a very basic level.

In that first example, I created a simple form helper class which was capable of taking different validator objects, or “strategies,” via one of its core methods, not surprisingly called “addValidator().” This flexible schema permits it to assemble multiple validation strategies at run time, in order to check distinct kinds of data without having to define a monolithic class that attempts to validate everything.

With the helper class ready to be used at will, the next step that needs to be taken to implement the Strategy pattern is to begin defining the isolated classes responsible for checking input data. Therefore, in this second part of the series I’m going to create a brand new strategy class that will be tasked with validating integer numbers. According to the model imposed by the pattern, instances of this class and other classes will be injected afterward into the helper, thus setting up a specific validation strategy.

Now, it’s time to leave the preliminaries behind and learn more on how to implement the Strategy design pattern in PHP. Let’s get going!

{mospagebreak title=Review: implementing the Strategy design pattern to validate input data}

As I said in the introduction, in the previous part of the series I defined a basic form helper class for accepting different strategy objects from the outside via its “addValidator()” method. Just in case you still haven’t seen the definition of this helper, below I reintroduced its source code, so you can analyze it and understand its driving logic. Here it is: 

(FormHelper.php)

<?php

class FormHelper

{

    protected $_validators = array();

    protected $_errors = array();

   

    // add a validator

    public function addValidator(AbstractValidator $validator)

    {

        $this->_validators[] = $validator;

        return $this;

    }

   

    // get all the validators

    public function getValidators()

    {

        return !empty($this->_validators) ? $this->_validators : null;

    }

     

    // validate inputted data

    public function validate()

    {

        $validators = $this->getValidators();

        if (null !== $validators)

        {

            foreach ($validators as $validator)

            {

                if (!$validator->validate())

                {

                    $this->_errors[] = $validator->getFormattedError();

                }

            } 

        }

        return empty($this->_errors) ? true : false;

    }

   

    // get validation errors as an array

    public function getErrors()

    {

        return $this->_errors;

    }

    

    // get validation errors as a string

    public function getErrorString()

    {

        $errors = $this->getErrors();

        return !empty($errors) ? implode(”, $errors) : ”;

    }

   

    // clear state of the form helper

    public function clear()

    {

        $this->_validators = array();

        $this->_errors = array();

    }  

}

Even though the form helper class defines only a few simple methods, the implementations of “addValidator()” and “validate()” are clear enough to demonstrate the logic behind the Strategy pattern. As you can see, instead of being one helper tasked with validating the supplied data, this responsibility has been delegated to the injected validator objects. This permits us to win a battle in two fronts: first, Composition is widely favored over Inheritance, and second, each validation process has been encapsulated into an isolated class (remember the sacred OOP principle that says “Encapsulate the concept that varies"?).

Okay, now that you’re familiar with the inner workings of the above helper class, it’s time to start defining the validators. As they will share a lot of common functionality, they will be derived from a generic abstract parent.

In the following segment I’m going to build this abstract validator class, so if you want to learn more details regarding this process, click on the link below and keep reading.

{mospagebreak title=Creating an abstract validation class}

Put in a simple way, the abstract validator that I plan to build here will rely heavily on PHP filters. Such filters are very useful for validating different data types in a painless fashion. With this abstract class seated on top of the hierarchy, creating refined child validators that check integers, email addresses and URLs will be a breeze.

Having said that, it’s time to show the definition of the abstract validator. That’s exactly what the following code fragment does. Check it out:

(AbstractValidator.php)

<?php

abstract class AbstractValidator

{

    protected $_value = ”;

    protected $_filter = ”;

    protected $_options = null;

    protected $_errorMessage = ”;

    protected $_errorPrefix = ‘<p>';

    protected $_errorSufix = ‘</p>';

   

    // constructor

    public function __construct($value, array $options = null)

    {

        $this->_value = $value;

        if (null !== $options)

        {

           $this->setOptions($options);

        }

    }

   

    // get supplied value

    public function getValue()

    {

        return $this->_value;

    }

   

    // set validation options

    public function setOptions(array $options)

    {

        if (empty($options))

        {

            throw new ValidatorException(‘Invalid options for the validator.’);

        }

        $this->_options = $options;

    }

   

    // get validation options

    public function getOptions()

    {

        return $this->_options;

    }

     

    // set the validation filter

    public function setFilter($filter)

    {

        if (!is_string($filter))

        {

            throw new ValidatorException(‘Invalid filter for the validator.’); 

        }

        $this->_filter = $filter;

    }

   

    // get the validation filter

    public function getFilter()

    {

        return $this->_filter;

    }

   

    // set the error message

    public function setErrorMessage($errorMessage)

    {

        if (!is_string($errorMessage))

        {

            throw new ValidatorException(‘Invalid error message for the validator.’);    

        }

        $this->_errorMessage = $errorMessage;

    }

   

    // get error message

    public function getErrorMessage()

    {

        return $this->_errorMessage;

    }

              

    // get formatted error string

    public function getFormattedError()

    {

        return $this->_errorPrefix . ‘The value ‘ . $this->getValue() . ‘ is incorrect. ‘ . $this->getErrorMessage() . $this->_errorSufix;

    }

   

    // validate the supplied value 

    public function validate()

    {

        return filter_var($this->getValue(), $this->getFilter(), $this->getOptions());  

    }

}

(ValidatorException.php)

<?php

class ValidatorException extends Exception{}

From the above code sample, it’s easy to understand how the “AbstractValidator” class works. It takes as an input argument the value to be checked via the constructor, and performs the actual verification process by using its “validate()” method, which is a proxy for the “filter_var()” built-in PHP function. The rest of the methods are pretty self explanatory; they allow you to set, format and get error messages, and assign additional options for a specific PHP filter. For obvious reasons the abstract validator doesn’t set a default filter to validate a supplied value, as this should be specified by the subclasses derived from it.

So far, so good. Now that you’ve grasped the logic driving this generic validator, at this point you should have a clearer idea of how this class fits into the schema imposed by the Strategy pattern. In reality, refined implementations of the abstract validator will be “strategy” classes that can be inputted directly into another class, such as the helper defined in the previous tutorial.

You’ll understand this concept better when I start creating some of those strategy classes, which will be responsible for checking predefined data types. Keeping this idea in mind, in the last segment I’m going to derive the first of these concrete validators. It will be tasked with checking whether or not a supplied value is an integer.

As usual, to see how this refined validator will be defined, click on the link below and read the lines to come.      

{mospagebreak title=Validating integer numbers}

If you’re anything like me, at this stage you want to see how to implement a concrete validation strategy, right? Well, considering that most of the functionality has already been encapsulated inside the previous “AbstractValidator,” building a strategy class that checks to see whether or not an inputted value is an integer is as simple as deriving the following concrete validator:

(IntegerValidator.php)

<?php

class IntegerValidator extends AbstractValidator

{

    protected $_filter = FILTER_VALIDATE_INT;

    protected $_errorMessage = ‘Please enter an integer value.';

}

There you have it. Didn’t I tell you from the very beginning that the implementation of the Strategy pattern in PHP was a fairly straightforward process? Well, the definition of the above “IntegerValidator” class shows this in a nutshell. It simply overrides the $_filter and $_errorMessage properties defined by its parent, which automatically provides it with the ability to validate integer numbers.

If you wish to test the above class as a standalone component, the task would be similar to coding the following script: 

$intValidator = new IntegerValidator(‘abcde’);

if (!$intValidator->validate())

{

    echo $intValidator->getFormattedError();

    /*

    displays the following

    The value abcde is incorrect. Please enter an integer value.

    */

}

else

{

    ‘The data is correct!';

}

As you can see, the “IntegerValidator” class is flexible enough to be used either as an isolated piece or as a companion strategy that can be injected inside another class. Obviously, the latter is the approach that I’m going to discuss in this case, but the earlier example should give you a good idea of how to create and use different validators based on the functionality encapsulated within their abstract parent.   

Final thoughts

In this second part of the series, I went one step further in the implementation of the Strategy design pattern in PHP. I proceeded to create a loosely-coupled class, which was charged with validating integer numbers. This validator (if the name is really applicable) is the first of a list of strategies classes that I plan to define in upcoming parts of the series.

Having already defined a class capable of checking integers, the next step that I’m going to take will consist of creating another strategy class. This time it will be responsible for validating float numbers. Do you want to learn the full details of this process? Then don’t miss the following tutorial!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan