CHAPTER 6 ■ OBJECTS AND DESIGN
Having said that, of course, I knew from the start that there would be text and XML implementations
of ParamHandler, and there is no question that this influenced my interface. There is always a certain
amount of mental juggling to do when designing interfaces.
The Gang of Four (Design Patterns) summed up this principle with the phrase “Program to an
interface, not an implementation.” It is a good one to add to your coder’s handbook.
Four Signposts
Very few people get it absolutely right at the design stage. Most of us amend our code as requirements
change or as we gain a deeper understanding of the nature of the problem we are addressing.
As you amend your code, it can easily drift beyond your control. A method is added here, and a new
class there, and gradually your system begins to decay. As you have seen already, your code can point
the way to its own improvement. These pointers in code are sometimes referred to as code smells—that
is, features in code that may suggest particular fixes or at least call you to look again at your design. In
this section, I distill some of the points already made into four signs that you should watch out for as you
code.
Code Duplication
Duplication is one of the great evils in code. If you get a strange sense of déjà vu as you write a routine,
chances are you have a problem.
Take a look at the instances of repetition in your system. Perhaps they belong together. Duplication
generally means tight coupling. If you change something fundamental about one routine, will the similar
routines need amendment? If this is the case, they probably belong in the same class.
The Class Who Knew Too Much
It can be a pain passing parameters around from method to method. Why not simply reduce the pain by
using a global variable? With a global, everyone can get at the data.
Global variables have their place, but they do need to be viewed with some level of suspicion. That’s
quite a high level of suspicion, by the way. By using a global variable, or by giving a class any kind of
knowledge about its wider domain, you anchor it into its context, making it less reusable and dependent
on code beyond its control. Remember, you want to decouple your classes and routines and not create
interdependence. Try to limit a class’s knowledge of its context. I will look at some strategies for doing
this later in the book.
The Jack of All Trades
Is your class trying to do too many things at once? If so, see if you can list the responsibilities of the class.
You may find that one of them will form the basis of a good class itself.
Leaving an overzealous class unchanged can cause particular problems if you create subclasses.
Which responsibility are you extending with the subclass? What would you do if you needed a subclass
for more than one responsibility? You are likely to end up with too many subclasses or an overreliance
on conditional code.