I haven’t explained to the public WHY I’m re-writing CD Baby from scratch, and I think the reasons would be VERY useful to you if you’re a programmer or webdesigner that may have started a project that will grow in ways you never expected.
When I started writing CD Baby back in 1998, it was only a hobby that I made to sell my CD, and some friend’s CDs.
I assumed it would ONLY sell CDs, nothing else, from my one location, in one language. That’s all I needed it to do. OOOPS!
- Need us to sell something much heavier than a CD? Can’t do it. In 100 different places in my code, it calculates shipping cost by just counting the number of items in the order. It has no concept of weight. (Also - no concept of NON-weight: like a download.)
- Want to sell something with different sizes/colors/variations? Can’t do it. The whole system is set up where an item is just an item and doesn’t understand the idea of variations or sub-items.
- My business could really use multiple warehouses, but the code can’t. The whole inventory/stock/shipping idea assumed there was only one warehouse.
- I wish the site could be in multiple languages, but like an idiot, I wrote all of my English words directly into my HTML code, so now to replace them with language-variables, I’d have to re-write every single line of HTML. MUCH harder than if I had just put all the language in one file to begin with.
The list goes on, in less-obvious ways. For years I had been saying, “If I could do it all over again…” - and that list got so long that it was time to do it all over again.
How to solve these problems and future ones I haven’t imagined yet?
EXPECTING CHANGE: question yourself anytime you assume anything will “always” be a certain way (examples below).
ENCAPSULATION: how to deal with anything that might change in the future: make sure it’s not assumed anywhere in your code. That there is only one definitive source for any bit of information or logic, and it hides its methods, so that if it needs to change, you don’t need to go change your entire program.
My example solutions to the problems named above:
- Shipping cost will be calculated in one single place. An order will get it’s shipping cost from this one definitive source, so that if my shipping rules change, (or if I start selling items that need no shipping), I only need to change that one file.
- Item will not assume it’s an album: more generic, they can be anything, or have have variations.
- Warehouse/Inventory/Shipping will not assume only one warehouse. I’m going to start calling our existing warehouse “warehouse #1″, and plan that there might be more.
- Words displayed on screen will not assume they are always English. I’ll put a variable where that phrase should go, and call it from a single language file, remembering the sentence structure might be different, so I can’t assume it will say, “Welcome, $username!”, because some languages might need to say, “You $username welcome are!”. (The language file itself uses printf-style, so it puts the external variable in a %s placeholder, where it’s appropriate for that language.)
- Can’t assume all languages read from left-to-right. Hebrew and Arabic are right-to-left.
- Can’t assume all currency is USD
- All visual presentation will come from a single CSS file.
I hope my bad experience helps you question some assumptions in your program. My best advice is making sure ALL words that display on the screen are taken from a single language-config-file. That one move will get you into the right mindset of expecting change and encapsulation. Then you can start noticing other things that your program/website is assuming will never change.
I just went looking for links that explain encapsulation to beginners, but I can’t find any good ones! Maybe I’ll have to write a future post with my take on explaining encapsulation to non-Java-geeks.