Good Design, Bad Code
I’ve been reading PHP 5 Objects, Patterns, and Practice, a great book exploring modern day design practices and the conventional wisdom of good software design. For serious PHP developers it’s a great update to the “gang of four” in a PHP context and really shows how PHP stands up as a serious development environment for the enterprise.
Unfortunately, all of this presents some serious misgivings about conventional software engineering methods that this book serendipitously stumbles upon. One of the code excerpts reads:
class Army extends Unit {
private $units = array();
function addUnit( Unit $unit ) {
foreach ( $this->units as $thisunit ) {
if ( $unit === $thisunit ) {
return;
}
}
$this->units[] = $unit;
}
...
I’m sure to the hot shit J2EE/EJB software architect this is perfectly good code in the context of a composite pattern. The above case represents a composite class that holds Unit objects, and the addUnit method simply adds Unit objects to the composite. The great part is this class will rarely, if ever, need to be updated since the business logic is separated into individual leaf classes and will be easier to maintain. Java programmers would be proud to see PHP like this.
On the other hand, every 15 year old hacker will now have something in common with old-school C programmers. They will recognize that this code is shit. It’s utter crap. It’s inefficient, sloppy, and scales poorly while being difficult to debug.
Have we as software engineers become so pig-headed that we no longer care about code efficiency and happily let a big-O(1) operation become a big-O(N) operation just because it uses the right pattern? When did software engineering mean you have to be stupid? Can’t I be a software engineer that follows good, disciplined, development methodologies while still favoring good code? We’re assuming that the intelligence of our design patterns will make up for the bad code.
For the J2EE crowd, PHP arrays are all associative, similar to a Vector class. In this case you’re adding individual leaf objects to a composite class; and every time you do you’re looping through an associative array to determine if the object already exists in the array. Each time you build this composite, which in a web environment is every page load, you’re doing a mountain of extra work. This is great for a small number of objects, but what if you have thousands, or even millions of objects at hand. This is what scalability is all about, right? When did our design patterns make us stupid?
The goal of software engineering is to produce good software, good software requires good code. Disciplined software engineering may have something to learn from the hackers who would recognize the bad code excerpts in this book.
