![]() |
|||||||||||||||||||||||||||
The Traditional ApproachWith traditional approaches a lot of effort is put into the software design, long before the the first line of code has been written. This is understandable, as this is justified with making sure that the system is being designed in an optimal way. This "design on stock" is normally called upfront design. In practice there are problems associated with upfront design. One of the problems is that during implementation new insights are emerging, which more often than not require a design change. De facto, the work that has been done before is thrown away, as ultimately the original (upfront) design is no longer needed in this particular part of the system. The reasons for such changes are many:
In other words: traditional approaches assume (to a certain degree), that requirements do not change; however, when implementing the system, there will be unforeseeable changes, which have to be taken into account. The XP ApproachThe issue of changing requirements does not go away by using XP. Instead XP simply assumes that such changes are the normal case. In conjunction with principle of simplicity the programmers are always implementing the smallest possible design. Over time the desing of the system evolves, so that ultimately the design emerges that is the best fit for the system. The XP programmer calls this simple design. Experience shows, that under normal circumstances, this is also the optimum design. How does this simple design emerge? Let's use an example from practice. For an internet portal, the first page to be created is the start page. The page is tested using the Microsoft Internet Explorer (you can replace this name by your favorite!). The page is finished. It is represented by a class named "index" (Note: The baseclass System.Web.UI.Page is part of Microsoft .NET framework):
This design is completely sufficient for a single page. Now we add a second page. This second page is intended for being used for references to other web pages and is therefore called "links":
This was easy as well. But now it becomes more interesting. Now, we want to add support for other browsers such as Netscape or Opera. And we all know, that all of the browsers are 100% W3C compliant..... OK, they are not! So we have to add code for browser specific code (here we will use C#):
This works, but it smells (e.g. switch is typically eliminated by using polymorphism). Furthermore, we would need to add this code to every single page of the site. And that is not what we want to do. Why Does It Smell?Why does this code smell? The answer is simple: Two concepts interwoven into each other. In object-oriented software you should always separate concepts. You do this by represented each concept by a class. In this particular case, the concepts are 1) the pure content and 2) the adaption for different browsers. It would be much better, if we could write:
But this is not sufficient yet. Someone has to instantiate the browser filter. Furthermore we need different filters, one for each browser. The following class hierarchy solves the latter:
We are not done yet. So far, we have just moved the code for the browser-specific adaptation to the filter classes. We still have to deal with the 'switch'-statement in each page. A New Base ClassAs 'System.Web.UI.Page' comes from a class library, we do not want or we cannot change it. In order to make our lives easier here, we introduce a new base class for all of our pages:
Now we move the switch-statement to the constructor of 'webPage'. This piece of code is the only place which needs to be modified, should we ever want to add support for more browsers to our web site. This is an instance of the 'once and only once' principle. Furthermore, we add a member variable 'm_browser' to the new class. The result is this class diagram:
The dynamic behavior is as follows: Wenn an instance of 'index' or 'links' is created (or of any other page, we might have), then the constructor of 'webPage' will be executed as well. There we check, which browser the client is using and we create an according filter. During initialization of the page, the method BrowserFilter.FixupPage() will be called polymorphically resulting in applying the correct adaptions for the page. Design Pattern "Strategy"'BrowserFilter', its derived classes and the method 'FixupPage()' represent an instance of the 'strategy' design pattern. This is therefore also an example showing that design patterns have their place in XP. More information about design patterns can be found in the literature (see book recommendations). The 'strategy' design pattern is described in detail in GOF. BenefitsThe first advantage, that can be seen, is that the essential concepts are now seperated in a clean way. Furthermore there is no more duplicate code. And finally is can be easily be seen, that it is much easier to add more page or support for more browsers with no or just a minimum impact (e.g. 'switch' in the constructor of 'webPage') on existing code. Tips
|
|
||||||||||||||||||||||||||