Kenneth Ismert
kismert at gmail.com
Tue Apr 12 15:48:47 CDT 2011
Let me give some examples of how I use function libraries, which might help illustrate what I'm talking about. Example 1: Factoring a Monolithic Business Class ======================================= I had a class, that I will call CPart, that had dozens and dozens of functions for dealing with parts. I had methods like CPart.Read and CPart.Save, with a CPart.Part property that I set before reading or saving a part. All was good until I got into situations where I just wanted to read an arbitrary part, without upsetting all of the delicate state that had built up for the 'Current' part. Yes, I could have created another instance of CPart, but it was monolithic, and represented the current (complex) state of the application, which seemed like a lot of effort just to read a part. So, for my first (bad) fix, I made optional parameters, like CPart.Read(Optional vPart As Variant), with internal code: If IsMissing(vPart) Then ' use member variable mvPart Else ' use given vPart End If ' specific code to read part ... Yes, my class inevitably got peppered with these optional parameters and If constructs, which started getting in the way of what the class was really trying to do, added extra complexity, and made it harder to debug and understand. During refactoring, I realized how I could simplify things: I built a module called MPart, with a function PartRead that took a required vPart parameter and returned a part structure or an error. The CPart methods lost their optional parameters and all the If statement nonsense, and the Part method's internal code reduced down to: tPart = MPart.PartRead(mvPart). External code could just call MPart.PartRead directly, without having to bother with creating and initializing a temporary CPart instance. Simplicity, readability, and testability improved all around. CPart shrank dramatically, making it easier to factor in the future. Example 2: Topical Function Libraries ============================= Over time, I have built up quite a few specialized modules for dealing with standard things in standard ways. For instance, MArray deals with arrays. MCollection holds very useful functions for Collections, similarly MString for strings and MVariant for variants. There are also more specialized libraries, like MMD5 for md5 hashes, and MMJD for Modified Julian Dates. There are lots of application-specific function libraries like MPart as well. These module functions have replaced sometimes a dozen half-assed and inconsistently written variations on a theme with one well-tested and thought-through piece of code that is portable among all of my applications. Moving standard code to a new application often reveals unknown weaknesses, which when fixed, strengthen the code for all applications. I find this to be a profitable way to bring consistency, flexibility and stability to my coding efforts. -Ken