I am a strong believer in reusing code and thereby minimizing the amount of code I need to write. Every time I write some new functionality I double check to make sure I have not already done something very similar already. There are two very good reasons for this.
First of all I want to get maximum benefit from each hour spent in front of the compiler. Working on this project only in my spare time means I don't have the luxury of doing anything not crucial.
Second, and even more important, is the principle of object orientated programming. If I'm writing code that is the same, or very similar, to something elsewhere in the project then something has gone wrong. It's a clear indication that something is going amiss with my design.
That being the case I need to investigate the problem and fix the architecture. The fix should negate the need for the duplicated code.
From small steps...
A result of this approach is that a new project should feel like evolution on a small scale. You start off by writing the simple elements of the project. As you then build upwards you create more complex structures that reuse many of the existing components. You're constantly moving up the evolutionary ladder.
Each step upwards only involves adding a small and reasonable set of features and feels quite manageable in itself. But after a few weeks have passed you look back and notice that all the small steps have evolved your design into an elegant and sophisticated structure. Well, that's the hope anyway!
If you've been following my coding updates then you should have been able to see this taking place. Let's quickly follow how the project has evolved so far.
In the beginning...
The first control created was about as simple and boring as can be imagined. We created a simple Panel component that is mostly going to be used to fill the client area of a window and give it the appropriate appearance.
Below you can see the control in use and it has the Microsoft Office 2003 look and feel. This is the only rendering class I have coded at the moment and so all the example pictures have this look and feel.
Let there be light...
Actually a more appropriate phrase would be Let there be a border... because out second control is the Group component. This consists of adding a border drawing ability with the existing background capability.
This was quick and easy to create because all of the infrastructure from the existing Panel was reused and extended. Although not obvious from this picture the components are much more flexible than they appear. You can use alpha blending, rounded corners, tiled images and so forth.
The Holy Trinity
Component number three took a little longer to construct because it involves drawing and positioning text. This is the Header control and it reuses the background and border functionality from the previous controls and then extends it.
This is an important landmark because the Header represents completion of the holy trinity of rendering. Almost all controls use a combination of background, border and content for display. If this sounds hard to believe then check out the next section which shows a good example of this in practice.
Add another dimension
What is the difference between a Button control and our previously completed Header component? Not a lot. In fact the only difference is that a Header has only a single palette and a Button has several.
Let's define what I mean by a palette. A palette is the triple combination of background, border and content settings. And by settings I mean the colors, font and other drawing styles you can specify.
So when the button is drawn normally we use one palette. When the user moves the mouse over the button area we switch to drawing with a different palette. On pressing the mouse down on the button we use yet another palette.
So the button really is the same as the header but instead of having one palette we have several, one for each of the states it can be in. Now you can see how we are reusing the existing infrastructure to get maximum benefit for adding a minimum of new code.
Our final picture below has two button instances, the left in the hovering over state and the right in the normal state.
To Infinity and beyond...
So what is our next step up the evolutionary ladder? The next control is going to be called the HeaderGroup and, as the name implies, it will combine the Group and Header capabilities into a useful little control. This might not sound like much of an advance, but trust me, it will turn out to be quite a handy little control.
So the next time you're coding...just think how much you owe to Darwin.