Membership
Main Menu
Forum Boards
Stats
- 20 tutorials
- 74,814 members
- 734,876 forum posts
- 13 blog posts
Tutorials
OO PHP Part 2: Boring OO Principles
Views: 20583
3 Defensive Programming
Defensive programming is ‘hope for the best, plan for the worst’. When you write a component, you don’t just assume that it will be used correctly. You validate the arguments and context and let the component fail when you find something at a miss.
We will build on this example, and provide more insight into defensive programming in the next chapter.
4 Heuristics
There are many “heuristics” in OOD that according to many should be accounted with.
These “lessons to be learned by others’ experience”, can indeed help you to avoid problems. They focus on a specific design decision, and are usually the result of trying to conform to OOD principles. OOD heuristics are not at all free of debate though.
Often OOD heuristics predefines the solution to a problem before you really encounter it. Therefore I like to think of them as ‘rules of thumb’: in most cases they hold true.
My advice: adopt these guidelines, but if they limit you in a way you can not compensate for, start looking for alternative solutions.
There are many more published and more descriptive heuristics, but I’m unable (and unwilling) to list all of them.
4.1 Avoid global data
Also known as ‘All global data is evil’. It pains me when I see people do stuff like this:
Do you have any idea what’s going on here? Neither do I. Not only is it unclear what is in those globals, it is also impossible to back trace the execution path by looking at the code. This makes it impossible to debug, unless you wrote it yourself and have a excellent memory. The latter definitely excludes myself.
But there is another type of ‘global data’: statically available data. Consider the following example:
Although the data is not in the global space, it is globally available, and it is quite easy to litter your application with unclear dependencies on some global data. You cannot make any assumptions about the contents of the data. Any components using this data are coupled to the global environment of the application!
In general, you’re better off using known data, shielded from the rest of the environment and passed only by clearly defined and stateful interfaces.
4.2 All properties should be private
This has its roots in Information Hiding as well as Defensive Programming.
Basically the argument is that you should have total control over your properties values, and it definitely has some merits.
Look back at the Defensive Programming example. If hungry was still public, we could pretend we fed Doggie a chocolate chip cookie, simply by setting hungry to 'I could eat some more.'.
But that’s cheating and nullifies the point of having that validation there. What we do instead is declare hungry private, and provide so called ‘accessor methods’, also known simply as ‘setters and getters’. Declaring all a class’ properties private also forces you to make a conscious choice about the accessibility of an objects internal data.
You’ve seen some getters in the User class. Those allow UserDataMapper read-only access to the User properties.
‘Setters’ allow you to validate the input before setting it on the object. In either type of method you may want to do some other things as well, like delegating to a aggregate object (Again, we will cover this later), or keeping track of the number accesses and printing “Congratulations on being the 1000th customer!”.
So, how do we make doggy adhere to all of this?
Since hungry is actually a property of Animal, we’ll have to go in and edit that first.
This is an example of very strict defensive programming: we do not trust children of Animal to provide a valid $hungry string, in fact, we do not even trust Animal’s own method eat to provide a valid string. This may seem like overkill, but it is in fact very good practice that will prevent bugs. If you look closely, you’ll see that the code above will in fact fail (‘not so much’ needs to start with a capital letter).
Mending Dog to work with the stricter Animal is trivial:
5 In conclusion
While this tutorial covers a lot of ground, you may have noticed that we are really only touching the surface. Much of this will be covered in more detail when we go into Design Patterns.
Look forward to a Class Diagram tutorial and a tutorial introducing the most common Design Patterns in the near future. Every tutorial will occasionally look back to provide frame of reference.
I hope you learned a lot, and provided you didn’t fell asleep, you probably did ;D
Till next time.
- « Previous
- 1
- 2
- 3
- 4
