Specifications for PHP5
php September 25th. 2008, 6:11pmOnly three months between posts. Not bad for me. For my sophmore blog entry I thought I’d share a PHP library implementing this idea by Evans and Fowler. Written for PHP5, it’s a library for defining custom specifications using composition and inheritance.
Let’s look at an example first to see what I’m talking about. Suppose you have a bunch of Person objects that look like this:
1 2 3 4 5 6 | class Person { public $id; public $first_name; public $last_name; public $age; } |
Now let’s say you need to test them, looking for entities that are valid Person objects, are under 35 years old and have the last name “Johnson.” These conditions might be expressed like this…
1 | $p->id >= 1 && $p->age < 35 && $p->last_name == "Johnson" |
…and it would satisfy your requirements. But, what if you need this same piece of validation logic in another place? Or perhaps you have another validator that includes all these conditions but also checks to see if the person’s first name is “John?” You could repeat expression shown above, or you could create a specification to be re-used and extended.
1 2 3 4 5 6 7 8 9 | class JohnsonSpecification extends AndSpecification { public function __constructor() { parent::__constructor( new AndSpecification( new GreaterOrEqualSpecification('id', 1), new LesserOrEqualSpecification('age', 34)), new EqualSpecification('last_name', 'Johnson')); } } |
What we have done here is create a binary tree of tests linked with AND operators to compose a complex specification that can be extended and re-used in our code. To validate a Person object, we would simply test the Person against our new specification:
1 2 3 4 5 6 7 | $spec = new JohnsonSpecification(); if ($spec->isSatisfiedBy($person)) { echo 'Woohoo!'; } else { echo 'Doh!'; } |
The library implements AND, OR and NOT nodes to compose specifications. The basic tests provided are: starts with, ends with, contains, equals, greater or equal to and lesser or equal to. From these building blocks, you should be able to create a wide range of custom specifications.
Where are they useful? As was shown in this article, specifications can be useful in validating objects. This is particularly useful for services that are passed objects from unknown sources, making sure valid input is received before any processing is done. They can also be used in a similar fashion to filter a stream of objects.
It might also be possible to use specifications to define queries to send to your data layer, though the practicality of this is up for debate. In any case, I hope you find this useful.
September 27th, 2008 at 6:01 am
Can it be usefull in sql query building?
I am very impressed by Hibernate HQL Criterias API.
I am veri intersted in analog of it on PHP5.
October 1st, 2008 at 5:27 am
[...] a recent entry to his blog Sean shows off a new specifications library he’s created to replace common [...]
October 1st, 2008 at 6:54 am
Jason E. Sweat did something very like this in his book “php|architect’s Guide to PHP Design Patterns” (2005). He cites the same URI in his chapter on the Specification pattern.
October 1st, 2008 at 7:07 am
Quite an interesting approach. It seems a bit like over-engineering to me since I can’t think of cases where I would’ve needed a similar condition check in many places, although I can imagine there could be some cases in more complex apps with a lot of business logic where this could be useful.
October 1st, 2008 at 6:21 pm
are you for hire?
October 2nd, 2008 at 4:01 pm
this was pretty dope. you may like to peek this src. http://play.feedthezombie.com/?src