One of the things I like about OO design can be shown by an example. Let's say I have a list of tasks that need to be carried out in order. For the sake of argument, I'll call the tasks INSERT, SELECT, and UPDATE, for no particular reason except to suggest that that tasks have both similarities with and differences from each other.
I go through the list and carry out each tasks in turn. First: the non-OO approach. This could be sketched out as:
function do(&$tasklist)
{
while(count($tasklist))
{
$task = array_pop($tasklist);
// $task is probably an associative array, with an element that
// describes whether it is an INSERT, a SELECT or an UPDATE.
switch(the type of $task this is)
{
case INSERT:
// The code for doing an INSERT task goes here.
// Or maybe a call to a function like "do_insert($task)"
break;
case SELECT:
// The code for doing a SELECT task goes here.
break;
case UDPATE:
// The code for doing a SELECT task goes here.
break;
}
}
}
There will be other functions optimise($tasklist), prioritise($tasklist), and so forth - all with similar structures to the above. Now I have a new kind of task: DELETE. So I have to go through all those functions - do(), optimise(), prioritise() - and add a case in each to handle DELETE tasks. If I miss one, the code will silently fail.
Now the OO approach. I'll have an abstract class called Task, which declares do(), optimise() and priority() methods, and extend it with classes Insert_Task, Select_Task, and Update_Task, which each contain the code for that type of task for that function - the code from that do_insert($task) function mentioned above, for example, would become the do() method of the Insert_Task task.
I'll also create a Tasklist class - I don't need to for the example, but I might as well while I'm about it. It will contain a property $tasks (which is an array of Tasks) and a method do(). The code for the Tasklist's do() method is (and, unlike the previous code, this is in full and not just a sketch):
function do()
{
while(count($this->tasks))
{
$task = array_pop($this->tasks);
$task->do();
}
}
And there is absolutely no mention of what sort of task $task is. When I want to create the DELETE task, I write
class Delete_Task extends Task
{
...
}
and fill in any properties and methods the DELETE task will need, including do(), optimise() and priority(). And all the code specific to Delete_Task will be contained between those two braces.
Now, because I wrote an abstract class Task that included the abstract method priority(), and Delete_Task is descended from Task, what happens if I forget to implement a concrete priority() method for Delete_Task is that the moment I try to create a Delete_Task, PHP will squeal with a "Fatal error: Cannot instantiate abstract class Delete_Task"; which is much preferable to failing silently - or having to write additional code to deal with the situation just in case.