The Relentless Pursuit of Excellence
I was at Starbucks for a decent part of the evening tonight, doing what I had hoped to be the last of my famous JPCRs (Java-Powered Code Review) for GenX.NET 3.0. Fortunately, I was wrong, it will not be my last review for this release. I say fortunately, tho I have been up for the past 6 hours making changes to the entire architecture AGAIN, because it is definitely for the better. I don't know what it is about White Chocolate Mocha Expresso that gets my brain going, but I think I'm hooked for life.
So what did I do that was so drastic? Well, I was staring at the code, and I had an apostrophe. Oops, I think I meant an epiphany. Anyways, something has been bugging me for the past month since I came up with the initial architecture: a nagging feeling that I was missing something in regards to extensibility. I can't say specifically what it was, except that part of my brain knew something was wrong, and couldn't elaborate it to the rest of my intellectual facilities. Well, tonight I found it.
*drumroll please*
The data formatting system (previously named "OutputProviders") was misnamed, and that the actual outputting system was too tied to the engine. The engine's job should just be to take ADO.NET data in, format it without having to know the format it will be in., and put it in it's destination, not having to know where that destination actually is. The problem was, all my destination code was hardwired to the system, and it was dying to get out.
So what I thought was a completely extensible system was only partially extensible, and a lack of planning could have seriously hindered the power of the component. So what did I do?
First, I went about renaming all of the existing OutputProviders and their related objects (the IOutputProvider interface and the OutputProviderFactory) and changed them to FormatProviders. This just makes more sense. Their job is to format the data,.
Next, I created a new OutputProvider system, nearly identical to the old one in architecture, but for the purpose of abstracting the delivery system for the new formatting system. In doing this, I also added a new OutputProvider for sending the resulting format as an e-mail attachment. Should come in handy for people that might be doing that anyways. It's also a feature that no other competitor has, but something that pretty much every GenX.NET customer does.
Finally, I updated the Build() method with 2 new overloaded methods, bringing the grand total to 4.
- The default Build method accepts no parameters, and uses both Factories to format and deliver the data.
- The next Build method accepts a custom IFormatProvider-compliant object, and uses it and the OutputProviderFactory to format and deliver the data.
- The third Build method accepts a custom IOutputProvider-compliant object, and uses it and the FormatProviderFactory to format and deliver the data.
- The final Build method accepts a custom IFormatProvider-compliant object and a custom IOutputProvider-compliant object to format and deliver the data.
I have to rework the actual IOutputProvider interface a little bit in the morning, but other than that, we're golden. It is now, without a shadow of a doubt, 100% extensible. Everything has been abstracted out, while still making it ridiculously easy to use.
So, what does this all mean for the component? Well, it means that you can take data, format it into a structure compliant with, say, a disparate system, and then submit it to that system. Here is a perfect scenario (which we will support in a future ComboPak):
Say you're a manufacturing company that ships all your parts out FedEx. Well, you're not gonna want to send 150 transactions over various times of day to FedEx... chances are you're gonna want to do a batch all at once at the end of the night. You could write up a SPROC to load up all that data into a DataSet. Then, with the FedEx Tagged Transaction FormatProvider, you could translate the data into a FedEx batch transaction. From there, you could use theFedEx OutputProvider, and submit that batch transaction directly to the FedEx system.
In a similar fashion, you could use the included XmlOutputProvider to accomplish the same task using FedEx's XML-based system. Just use your SPROC to map your database table names to the expected FedEx XML structure.
This is really only the beginning. You could do this for any number of systems, including OracleSmallBusiness.com, ITransact.com, or any other system that does not make use of web services. Heck, you could even have it submit to a web service if you wanted to, tho I'm not entirely sure why yet.
At any rate, I finished up the documentation editing for the FormatProviders, and after spending a bit more time on the OutputProviders tomorrow, the control should be 100% wrapped up. Then I'll just have to write the 4th version of the marketing materials for v3 to reflect the changes, and spruce up my website.
So why was this post entitled "The Relentless Pursuit of Excellence?" Because you should never accept that someting can only be done a certain way just because everyone says so. You shouldn't allow poor practices, ridiculous deadlines, or miscommunication in any way affect the quality of your code. And because you never know when your next JPCR (if you're not doing them yet, you should be) will give you YOUR next epiphany.