A number of years ago, we built a web site designed for change. At the time, no thought was given to design patterns, but instead we knew that the site would change based on experience, and were acutely aware of making sure that the site was set up for accepting change without having to redo it.
This was a case where the plan worked too well. The site is easy to update and as a result, we really haven't bothered to take the time to rework the site to incorporate new concepts. It's starting to look a little old-fashioned, and we'd like to upgrade the version of Flash so that we can optimize video and all the new features in Flash CS3 and ActionScript 3.0. However, the plan illustrates a basic truth about software in general and web development in particular. You're going to spend more time on maintenance and changing a site than you are building it in the first place. As a result, you need to plan for maintenance and extensibility, and not just to get things working right in the first place.
Had the web site that had been planned for change been done with design patterns, not only would it be able to adapt to change, we wouldn't have to scrap the current design and start all over from scratch to extend the site. That is, only part of the planning process should address change of a static category. You also need to plan for extending the site to incorporate more than what you originally planned to change. That is, you may need to add new materials to change.
While the web site described as built for change has persisted, it has not evolved. The site has been easy to maintain because its main function loads an image, a text file, and menu items for a given product. By either changing the label on an existing button or adding a button, changing and adding products is pretty simple as well. So it has a little extensibility in the sense that its not fixed to a single product.
However, the site really isn't set up for robust extensibility. For instance, adding a blog to the site or changing the way that the menus work would take the same amount of re-structuring as it would to start from scratch. So, while changing products in the site is simple, changing the site is not. Structurally, the site looks something like Figure 1-9—The Big Function:
It doesn't matter whether the big function is directly instantiated, gained through inheritance, or a delegate of composition. It has no flexibility other than the parameter to tell it what to place on the stage. If its algorithm is changed, it could wreck havoc on its use. You can view it as tough and inflexible because it gets one job done in one way. Alternatively, the big function can be seen as dainty and fragile because of its dependency on a single routine, and because it is subject to freeze up when interacting with new elements in the application. In any case, it doesn't lend itself to a flexible site, and we should rethink it.
The plan using The Big Function, even though it has limited flexibility, is bound to break down and fail in the long run. To avoid getting stuck with an inalterable application, you need to consider some granularity in your design. In this context granularity refers to the amount of functionality each of your classes has. The trade-off between full functionality and granularity is that the more functionality a class has, the more it will do all by itself. After all, most classes we create are developed to add the functionality of several built-in classes. However, sometimes less is better. The less functionality a class has, the more components in your application its functionality can employ. Figure 1-10 shows how this granularity might work.
The Big Function from the last section has been broken down into three smaller (more granular) functions. Using composition, the functionality of the Big Function is duplicated. However, the granularity gives the developer far more options in the future. In the context of developing a real-world application, your design must look over the horizon. That is, you need to plan for both possible and unknown changes. Figure 1-10 shows some possible future extensions to the application (those with dashed lines). The value of granularity is that the new classes can use some or all of the more granular functions. That would be impossible with the single Big Function from the previous section. Likewise, new functions can be added and used with the old ones.