I guess I feel I’m not challenged enough at my job because sometime I deliver way more than I was asked (which got me in trouble once or twice).
I was once asked to develop a simple cache manager. We were downloading documents from a server, and we wanted to have a local cache so we would only download them at most once a day.
The specifications were something like this :
TOurDocumentCacheManager = class public [...] procedure WriteToCache(const DocumentId : string; Document : TOurSpecificDocumentClassInstance); function ReadFromCache(const DocumentId : string; Document : TOurSpecificDocumentClassInstance) : Boolean; [...] end;
I felt this was WAY too specific for a job that is pretty general. So I altered the specifications like this :
ICacheable = interface(IStreamPersist) function GetUniqueId : String; end; TCacheManager = class public [...] procedure WriteToCache(Document : ICacheable); function ReadFromCache(Document : ICacheable) : Boolean; [...] end;
So, instead of having a cache manager that can manage a single type of document, we have a cache manager that can manage them all.
Believe it or not, that still landed me a few complaints, though all easily refuted. One of which might even come to your mind… “What if we want to cache an object from a 3rd party? We can’t magically add ICacheable to the object!”. And this is a valid point, until we realize writing a ICacheable wrapper around an object is simpler than writing a new cache manager.
So… I guess the point I was trying to make here is how easy it is to limit the potential of the code we write. Sometime, it doesn’t involve much (if any) extra work to make our code more reusable, and it’s pretty much always worth it.