Home arrow PHP arrow PHP: Effects of Wrapping Code in Class Constructs

PHP: Effects of Wrapping Code in Class Constructs

In this first part of a two-part tutorial, I use a somewhat contrived example to show why you should avoid coding static helper classes in PHP.

TABLE OF CONTENTS:
  1. PHP: Effects of Wrapping Code in Class Constructs
  2. Converting the Helper
By: Alejandro Gervasio
Rating: starstarstarstarstar / 0
December 28, 2011

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

Let’s be honest: how many times have you found yourself writing a custom static helper class, or putting your hands eagerly on one that came bundled with a framework, from the many available out there? If you’re anything like me, the answer will be at least … a few (remember that the first step to healing is admitting you have a problem). Static helpers seem to be a great idea at first glance, as they’re reusable components that don’t require any kind of expensive instantiation for doing common tasks, such as determining base URLs and paths or validating incoming data. But the sad and unavoidable truth is in many cases they’re simply wrappers for procedural code, which has been elegantly hidden behind a “class” construct.

So what's wrong with this? Well, even in the most harmless situations, when you use a static helper that produces a deterministic output, you’re actually throwing away the advantages that OOP provides. First and foremost, you can’t exploit the functionality of Polymorphism, which is a serious drawback indeed. Also, while it’s possible to further extend a static helper via Inheritance without infringing the Liskov Substitution Principle, you can’t create new helpers without breaking up existing client code, hence violating the Open/Closed Principle.

This doesn’t mean, though, that you should stop using your current helpers or completely avoid building new ones in the future. However, with a little willpower and the use of good object-oriented practices, you can easily create “instantiable” helpers. These will not only be shielded from the aforementioned issues, but will also be able to be injected into other objects’ internals. Add to this the ability to be  tested in isolation, mocked up and so forth, and you’ll end up with a firm groundwork that will let you build more robust and solid OO applications.

As usual, the best way to demonstrate why static helper classes can make your life a lot harder (and how easy it is to turn them into “injectable” instances) is by example. In this two-part tutorial I’ll be setting up a few in PHP (which can be ported to other languages, of course) to help you grasp the pitfalls of this approach, and how to fix them.

Building a Static Validator Class in PHP

As I explained at the beginning, it’s fairly simple to prove why static helper classes can cause a lot of headaches, especially when building scalable object-oriented applications. The first step of this proof is to create a trivial helper that will be responsible for validating different types of input data, such as integers and floats, URLs and email addresses.

Please take a look at my sample validator helper, whose implementation looks like this:

(Library/Helper/Validator.php)

<?php

namespace Library\Helper;

class Validator
{
    private function __construct(){}
   
    /**
     * Validate an email address
     */
    public static function validateEmail($email)
    {
        return filter_var($email, FILTER_VALIDATE_EMAIL);   
    }
   
    /**
     * Validate a URL
     */
    public static function validateUrl($url)
    {
        return filter_var($url, FILTER_VALIDATE_URL);  
    }
   
    /**
     * Validate a float number
     */
    public static function validateFloat($value)
    {
        return filter_var($value, FILTER_VALIDATE_FLOAT);
    } 
   
    /**
     * Validate an integer number
     */ 
     public static function validateInteger($value)
     {
         return filter_var($value, FILTER_VALIDATE_INT);
     }     
}

There's not much to say about the above “Validator” class, as it only implements a set of static methods, which use a few PHP filters to validate the previously mentioned data types. However, don’t let the naive nature of this static validator fool you, since it comes with some issues worth noting. First, it’s nothing but a bag of procedural functions, which don’t expose explicit pre/post conditions or even class invariants.

Secondly, the only way to extend its current functionality is by means of Inheritance. This naturally infringes the commandments of the Open/Closed paradigm, as no instances that adhere to some interface can be passed around. And last but not least, the class is clearly doing too many things, hence breaking the Single Responsibility principle.     

For obvious reasons, my seemingly inoffensive helper class is in reality a wild creature running through distant woods instead of treading the straight and narrow road of good object-oriented practices. For the sake of completeness, however, below I wrote a simple script that shows how to use it for checking some trivial data. Here it is:   

<?php

// include the validator helper
require_once __DIR__ . '/Helper/Validator.php';

use Library\Helper\Validator as Validator;

// validate a URL
if (!Validator::validateUrl('http://www.devshed.com')) {
    echo 'The supplied URL is invalid';
}

// validate an email address
if (!Validator::validateEMail('user@domain.com')) {
    echo 'The supplied email address is invalid.';
}

// validate a float number   
if (!Validator::validateFloat(2.5)) {
    echo 'The supplied value is an invalid float number.';
}

// validate an integer number
if (!Validator::validateInteger(10.5)) {
    echo 'The supplied value is an invalid integer number.';
}

/* displays the following

The supplied value is an invalid integer number.

*/

Even though the helper actually does its business as one might expect, it’s clear to see its procedural roots. But, there’s no need to start pulling our hair out, as turning the class into a fully-extendable, object-oriented compliant structure is a simple process. In fact, the entire “conversion” is reduced to breaking the class into several instantiable subclasses, which will be implementers of the same interface.



 
 
>>> More PHP Articles          >>> More By Alejandro Gervasio
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PHP ARTICLES

- Hackers Compromise PHP Sites to Launch Attac...
- Red Hat, Zend Form OpenShift PaaS Alliance
- PHP IDE News
- BCD, Zend Extend PHP Partnership
- PHP FAQ Highlight
- PHP Creator Didn't Set Out to Create a Langu...
- PHP Trends Revealed in Zend Study
- PHP: Best Methods for Running Scheduled Jobs
- PHP Array Functions: array_change_key_case
- PHP array_combine Function
- PHP array_chunk Function
- PHP Closures as View Helpers: Lazy-Loading F...
- Using PHP Closures as View Helpers
- PHP File and Operating System Program Execut...
- PHP: Effects of Wrapping Code in Class Const...

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: