Always looking for new or intuitive ways to write better code is a constant struggle because we all know that developers are human and deadlines are nearing.
The core concept here is to make sure that every line of code you write is correct, manual code reviews, pair work and unit tests are all good tools, however this takes it a little further.
Every statement or set of statements should evaluate to TRUE, and never executed if it's prerequisites aren't met.
This can be a little tricky in PHP due to the sometimes terse nature of language constructs and the lack of anonymous code blocks, although much can be achieved.
function validate( $var1 )
{
assert( ($var1 < 50 AND $var1 > 45) OR ($var1 < 90 AND $var1 > 85) );
}
validate( 49 );
validate( 87 );
Multiple statements can be added afterwards, and because of the asserts we can presume that by the time they are execute all previous conditions have been executed.
A more real-world example:
function insertUser( Database $db, User $user )
{
assert(
! is_null($user->id)
AND strlen($user->username) > 4
AND strlen($user->username) < 20
AND !empty($user->password)
);//assert
if( $user->has_blog )
{
assert( $user->id = $db->insert($user)->into('table') );
assert( $blog = new Blog($user_id) );
assert( $blog->id = $db->insert($blog)->into('othertable') );
$user->blog = $blog;
}
return $user_id;
}
As you can see, validation is stripped down into the logical components acting as a barrier or contract, while the second section is asserted on every major statement.
We're asserting that if any of these statements fail, then there has been a programming error or a failure outside of this code as it's state has been validated at every step. This will lead to better code because at the expense of a few more characters the developer actually has to write less error checking code, less conditional statements and account for less situations - focusing purely on the logic of the application.
As soon as user-input comes into the equation you need to be able to fall back and gracefully stop, this method is not suited for for user input validation, it thrives in the middle of an application and complements unit tests perfectly.
One feature I would love to see in PHP, in the spirit of this article, is to have the PHP compiler automatically assert every statement automatically or for selected code blocks. For example:
assertive {
! is_null($user->id);
$len = strlen($user->username)
AND $len > 4
AND $len < 20;
! empty($user->password);
if( $user->has_blog )
{
$user->id = $db->insert($user)->into('table');
$blog = new Blog($user_id);
$blog->id = $db->insert($blog)->into('othertable');
$user->blog = $blog;
}
}
return $user_id;
Pros
- Continuous testing of production-grade code.
- Good coding habits.
- Fast error detection/feedback to the developers.
- Safety net when refactoring.
Cons
- Additional weight of entry and exit contracts.
- Slight overhead of asserts.
- ???
Leave a Reply