TomNomNom.com

Blogging since 2008 until 2010

Objects before classes makes for a cleaner API

Quite often I find myself writing a new class for the hell of it - or in the hope that it will come in useful for some project or other. From all my experience in writing random classes, the most important bit of advice I can give is this: **write the code using the class before you write the class itself. **

If you're a relatively newbie OO programmer, it can be very easy to get tied up in the details and focus on writing clean code in your classes. There's nothing wrong with that in itself, but it can make for real headaches later on when you try to use them. As an example, here's a rather fruity class I wrote without bothering to think about how it will be used:

<?php
class Fruit {
  private $name;
  private $color;
  public function getName(){
    return $this->name;
  }
  public function setName($name){
    $name = ucfirst($name);
    $this->name = $name;
  }
  public function getColor(){
    return $this->color;
  }
  public function setColor($color){
    $color = ucfirst($color);
    $this->color = $color;
  }
}

The class may be clean and tidy, but having to call setName() and setColor() for every fruit I want to create is going to end up being a serious pain. Let's say I want to eat the fruit with a little function like this:

<?php
function eatFruit(Fruit $fruit){
  echo 'Om nom nom! I\\'m eating a '
      . $fruit->getColor() . '
 '
      . $fruit->getName();
}

I would have to create my object, set it's name and color, and then call the eatFruit() function:

<?php
$apple = new Fruit();
$apple->setName('granny smith');
$apple->setColor('green');
eatFruit($apple);

That might not seem like masses of code to get my lips around some tasty fruit, but it could be a lot easier. Let's start from the other end and write a use-case for the fruit before writing the class.

<?php
eatFruit(new Fruit('granny smith''green'));

That's a whole lot easier in my book. I could be eating four times as much fruit per line than I could before! The class doesn't even require that many changes to make it work; just a constructor...

<?php
class Fruit {
  private $name;
  private $color;
  public function __construct($name = ''$color = ''){
    $this->setName($name);
    $this->setColor($color);
  }
  public function getName(){
    return $this->name;
  }
  /*...And the same as before...*/
}

Although there's more code in the class cluttering it up, it only has to be written once.

I admit this may be an over-simplified example, but I think it carries the right message: don't worry about making your classes bulky and complicated if it means your code that uses them will be simpler.

First posted: Mon, 12 Oct 2009 09:49:57 +0000