Login

Verifying Float Values with the Strategy Design Pattern

In this third part of a series on validating incoming data with the strategy design pattern, I create a brand new strategy class that can check whether or not a supplied input value is a float number. The addition of this class extends the capabilities of the sample validation program that I’m building in this series.

Design patterns are well-known, reusable paradigms that allow developers to solve certain problems in a more efficient way, even though their implementation is flexible and not tied to a specific programming language. Due to their variety, they can be placed in different categories (creation, structural, behavioral, etc.), but their rather fuzzy boundaries tend to create large gray areas between them.

It’s valid to say, though, that a number of patterns can be of great help, especially when developing more flexible and scalable applications. A good example of this is the triad made up of the Decorator, Composite and Strategy patterns, which share a common feature worth stressing here: all of them tend to favor Composition over Inheritance.

Unlike its handy partners Composite and Decorator, which tackle some common software development problems in an elegant and efficient manner at the expense of a steeper learning curve, Strategy is incredibly easy to implement. This becomes even more evident when using a language as friendly as PHP. When applied in an appropriate case, the Strategy pattern is a powerful tool that permits you to merge two of the big pillars of the object-oriented paradigm: first, to use Composition over Inheritance, and second, to encapsulate the concept that varies.

To demonstrate how useful and easy it is to apply the Strategy pattern in a real-world case using PHP, in the two previous tutorials of this series I started building a modular web application. It was tasked with validating incoming data through a set of loosely-coupled strategy classes. So far, I’ve shown how to provide this sample program with the ability to check integer values via an isolated “integer strategy” class, but it’s necessary to extend the program’s current functionality by adding a few more validation classes to it. Therefore, in the following lines I’m going to develop a brand new strategy class, which will be charged with checking whether or not a supplied value is a float number.

Are you ready to learn more about this process? Then begin reading right now!

{mospagebreak title=Review: the sample classes developed so far}

As usual, before I get my hands dirty defining a brand new strategy class responsible for validating float numbers, first I’d like to spend a few moments reintroducing all of the sample classes developed so far in this series. This way you can analyze them in more detail and understand more clearly how they fit with each other.

Having said that, here’s the definition of a simple form helper. It accepts different strategy classes via its “addValidator()” method. This permits it to validate distinct types of data with minor hassles. Take a look at it, please:

(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();

}

}

As I said before, the previous form helper relies on the benefits offered by Composition to inject a bunch of data checking classes from the outside, which can be used to easily assemble different validation strategies at run time.

Since the source code of this helper is pretty easy to follow, I suggest you move on and look at the definition of the following abstract validator. It encapsulates the common structure and logic of a generic validation (read strategy) class. Here it is:

(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.’);

From the above code fragment, it’s clear to see how this abstract validation class does its thing. It simply uses the functionality provided by PHP filters to validate an inputted value, previously stored on the protected “$_value” property. Not surprisingly, the workhorse method of this class is called “validate()” and is responsible for checking whether or not the mentioned value is valid.

This abstract structure encapsulates a lot of generic logic and is accommodated comfortably on top of the hierarchy. Therefore, defining refined implementations of it, which can be used to check different types of data, such as integer numbers, is as simple as creating the following subclass:

(IntegerValidator.php)

<?php

class IntegerValidator extends AbstractValidator

{

protected $_filter = FILTER_VALIDATE_INT;

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

}

That was simple to code and read, wasn’t it? By simply overriding the “$_filter” and $_errorMessage” properties declared by the abstract validator that you just saw, it’s possible to create a custom validation class in the blink of the eye. This class can be injected either as a strategy object into the previous form helper or used as a standalone component.

However, as I explained in the introduction, my goal here is to progressively build a modular program aimed at checking incoming data by using different strategy classes. Obviously, in its current state this sample program is capable of validating only integers, which isn’t very useful. So, it’s time to add a brand new strategy class to it that permits it to check whether or not a supplied value is a float number.

The full details regarding the definition of this class will be shown in the following section. Thus, to learn more, click on the link below and keep reading.

In reality, building a strategy class that can validate float numbers is nearly identical to creating one that checks integers, which we already did in the previous segment. Nonetheless, the best way to prove the truth of my claim is by means of some functional code, so below I included the definition of this brand new strategy class. It looks like this:

(FloatValidator.php)

<?php

class FloatValidator extends AbstractValidator

{

protected $_filter = FILTER_VALIDATE_FLOAT;

protected $_errorMessage = ‘Please enter a float value.’;

}

There you have it. As you can see, building a refined class that validates float numbers is reduced (again) to overriding the already familiar “$_filter” and “$_errorMessage” properties defined by the parent abstract validation class. Of course, “FloatValidator” is as flexible as its partner “IntegerValidator,” so it can be used in conjunction with other classes or in an isolated fashion.

The latter option deserves at least a quick look. So in the last section of this tutorial I’m going to set up a basic script that will show how to use the previous “FloatValidator” class in an independent manner.

Now, don’t waste more time; read the lines come.

{mospagebreak title=Using the FloatValidator class as a standalone component}

To demonstrate in a quick and dirty way how flexible the earlier “FloatValidator” class can be, below I coded a somewhat trivial script which shows how to use the class as a standalone component. Check it out:

// create an instance of the float validator class

$floatValidator = new FloatValidator(‘This is a test string’);

// validate the supplied value

if (!$floatValidator->validate())

{

echo $floatValidator->getFormattedError();

/*

displays the following

The value This is a test string is incorrect. Please enter a float value.

*/

}

else

{

echo ‘ The data that you entered is correct.’;

}

Done. As you can see, using an instance of the previous “FloatValidator” class in an independent way is a straightforward process that doesn’t bear any further discussion. However, it’s worth pointing out that the above script may produce erroneous results, particularly when checking numeric values. These glitches occur due to the behavior of the FILTER_VALIDATE_FLOAT constant. Thus, if you need to fix these little bugs, please read the official PHP filters documentation here: http://php.net/manual/en/ref.filter.php

Having clarified that, I’m sure that at this point you have a clearer idea of how useful the Strategy pattern can be when checking incoming data in a modular way. However, the sample validation program being developed here still has a pretty limited functionality that needs to be enhanced. This will be done, of course, in future articles in this series.

Final thoughts

In this third installment of the series, I proceeded to create a brand new strategy class, which was provided with the functionality required to check whether or not a supplied input value is a float number. While the addition of this class does contribute to extending the capabilities of the sample validation program that I’m currently building in this series, it’s fair to say that it can be enhanced even further.

You may be wondering how. Well, it’d be relatively easy to add another strategy class to the program, and make this one able to validate email addresses. This would make it possible to assemble a wider range of validation strategies at run time, which speaks for itself about the benefits introduced by Composition. In the next article I’m going to define this new email checking class.