2007-11-09
An object oriented design mistake illustrated
Being written in Python, DWiki uses a certain amount of object oriented
design (not huge amounts; it has basically no inheritance hierarchy
among its classes, although they have various interrelations). In
particular, it has a Page
class that represents a particular real page
at the model level (not the presentation level, which is where template
processing and so on happens).
Here is a trick question: is a page's URL a property of the page?
(That is, should the Page
class have a url
method or property.)
It certainly seems intuitive that a page's URL is a property of the page, and when I started writing DWiki I started out trying to code things up this way. It turned into a disaster, because the intuitive answer is wrong. In a web server environment, it turns out that a page's full absolute URL must be built from a combination of data from three objects:
- the page itself is what knows its path relative to the root of the model (technically the model's data store).
- the configuration is what knows the URL of the model's root, to which the page's path is added to get the absolute URL.
- only the request knows what the web server's hostname and port is,
because that comes from the
Host:
header in the request itself.
(A DWiki instance doesn't require you to talk to it with any particular hostname and port, because I dislike burning that sort of system-level information into what is effectively application configuration.)
One of the reasons I didn't realize this up front before I started coding DWiki was that I hadn't done enough work with HTTP and the web to really be aware of all of the issues; in fact I was so ignorant that I didn't realize I was ignorant, so I forged on in blithe confidence and ignored various warning signs.
(And I have to admit that I made some terrible howlers in this area even after I had DWiki and WanderingThoughts going. Writing DWiki has been not merely educational, but repeatedly educational.)