|Keep It Simple, Stupid|
How to avoid (or handle) module interface changesby chester (Hermit)
|on Oct 21, 2005 at 18:16 UTC||Need Help??|
Just some random thoughts about some things I've encountered recently due to some poor judgments on my part, and some thoughts about the concept of data-hiding.
At work I have a bunch of Perl scripts that access some central data. The data is a hideous mess and I'm unable to clean it at its source. Because I found myself re-parsing the same data over and over, I threw it into a module to attempt to make it easier to access; the module parses the data, organizes it and outputs it as needed. This is a good place to use OOP, I think: provide a cleaner interface to dirty data.
My problem is that the module's interface (the way it stores data internally, the way it's initialized, the way it sends data back to the user) is functional, but far from optimal. What I THOUGHT I'd need to do with the data is different than what I actually need to, for one thing.
Lesson learned: YAGNI! I first heard that term in the chatterbox a few days ago; if only I'd heard it 3 months sooner. Don't make guesses at what you'll need someday, because you're probably going to be wrong. Instead design something with separate, clean pieces that you can later put together to create anything you need.
Now, I know enough about OOP that I'm not directly accessing the module's guts in my scripts; I have accessor methods. But my accessor methods aren't the best. For example instead of returning a hash of hashes of hashes of hashes and letting the user deal with it, what I really should have been doing is returning an array of specifically what the user asked for. Doing that way would be good because 1) it's less confusing for the user, 2) the module can initialize/fetch parts of the data at a time as needed, instead of all at once, 3) it forces me to store the data in a cleaner way in the module, 4) it lets me change the backend without breaking the frontend. etc. etc. I wasn't doing quite enough parsing and data-simplification at the module level; using my module was easier than using the original raw data, but it wasn't as easy as it could have been. The bad thing is that as a result, my scripts are tied too tightly to the original modules' interface (or the structure of the data the module outputs).
Lesson learned: don't puke any more data at the people who are using your modules than they specifically ask for and require.
So the best solution is to AVOID interface changes. But barring that, assuming a change is required or greatly desired, the quesiton is : How do you handle interface changes when a lot of people are still using your old interface?
There are various ways I see of correcting this problem:
I'm unsure which option is the best. The answer is probably "it depends". (Isn't that the answer to all questions? (Obvious answer: It depends on the question.)) But do you have any other thoughts or experiences?