Getting the OO design write - with PHP a example
Archive - Originally posted on "The Horse's Mouth" - 2010-08-14 14:58:18 - Graham EllisOne of the great beauties of Object Oriented Design is that you can say "I want to handle a type of data that's based on an xxx", and if someone's already written (and made available) the code for an xxx, all you have do do is define the additions and differences, rather than starting from scratch. So this means that OO is great for applications where you have a whole lot of different types of thing with similar, but never the less different, behavior.
Let's say, for example, that I'm writing a whole lot of code to help Henry, who lives with his girlfriend Emma, a cat, and a whole lot of dogs, look after his dependents. Before you accuse me of being sexist, I'm sorry to have to tell you that whilst Henry is gainfully employed at the moment, Emma is between jobs as she used to work for Sun4U:

OK - glad we cleared that one up ;-) ...
So Henry has Emma, Gypsy (a lurcher), Wover, Spot (a dalmatian!), Rufus, "Oy - you", and Charlie the cat.
Now - design MATTERS - and Henry should start with a common base for shared code and build on that. In fact, he was on our recent Object Oriented Design in PHP course and went away with a class called "animal" that forms a good basis for his project. So:
• A cat is a type of animal
• A dog is a type of animal
• A girlfriend is similar to an animal
• A lurcher is a type of dog but has subtle differences
• A dalmatian is a type of dog (but behaves just like any other dog)
And from that, Henry can draw up a diagram that shows how his classes relate to each other. The black circles on this diagram show each of the classes, and the lines rising from each link to the classes that are extended from it (i.e. inherit from it). You'll note that we do not have a separate class for "dalmatian" as a dalmatian is just another dog, but we do have a separate class for a lurcher as they're vocally different to other dogs.

Look at the completed design, and you'll see that I have added yellow lines to show you how the various methods work when you call them up on an object of type lurcher:
• The constructor is inherited from the base animal class
• getweight, getname and olderthan also come from the base animal class
• geteage comes from the dog class ... and ...
• says is actually defined in the lurcher class (overriding the one that's in the base animal class!)
I can now write a test piece of code to see how my design stacks up - this is a sort of specification check to ensure that I've not missed anything out:
$hounds = array(new lurcher("Gypsy",30,4),
new dog("Wover",60,20),
new dog("Spot",15,9),
new girlfriend("Emma"),
new cat("Charlie",4,12),
new dog("Rufus",10,10),
new dog("Oy - you",6,8));
foreach ($hounds as $hound) {
$called = $hound->getname();
$heavy = $hound->getweight();
$old = $hound->geteage();
$sound = $hound->says();
print ("$called weighs ${heavy}kgs, is aged $old and says $sound\n");
}
Having got the design worked out carefully, I can then write the class code secure in the knowledge that I won't have too many nasty surprises and changes of direction also on the way. The example code that I wrote during the course, basically translating the diagram above may be seen [here].
The output from the code above ... and, yes, I have checked it, looks as follows:
Gypsy weighs 30kgs, is aged 28 and says [nothing]
Wover weighs 60kgs, is aged 140 and says "moo"
Spot weighs 15kgs, is aged 63 and says "moo"
Emma weighs 53kgs, is aged 21 and says "Will you come shopping with me"
Charlie weighs 4kgs, is aged 72 and says "miaow"
Rufus weighs 10kgs, is aged 70 and says "moo"
Oy - you weighs 6kgs, is aged 56 and says "moo"
My example code also contains the logic to find the older (of two) and the oldest (of a whole array) of animals (or objects which are subtypes of animals). There's a little more about that on a previous article [here].