- Scalability - able to grow according to need.
- Portability - able to run on multiple platforms or being able to reuse code (sometimes this gets split up into "Portability" and "Reuse" though I think of them as the same thing).
- Flexibility - being able to modify for differing concerns.
I was writing a piece of code and writing an explanation as to why I was still using gtk2 rather than moving on to gtk3 - mainly that the official documentation was copied straight over from gtk2 but does not match up with the gtk libraries (for example the documentation for the alignmentbox still talks about margins but the gtk3 implementation doesn't have any such thing).
It's lead to having to write some documentation around how to replace that particular piece of code - basically the interfaces it needs to provide. This leads to the program being able to have any interface the developer so chooses. For example, if working on a KDE system, then it's fairly trivial to write a module that uses the qt toolkit. Or even, a text based (ncurses?) interface.
But that flexibility wouldn't have come around without a particular need. For example, I was looking at Gherkin. The application that initially sets up their computer. So it asks them for their school, username etc. and sets up the system accordingly.
And then we have the high school scenario. Students take options - such as electronics. A couple of departments had been asking for applications to do X and Y and the students having been having to download and install them themselves. When I find people having to do things themselves on a computer, I've been asking myself, is there an easier way of doing it?
So I figured the initial set up application should present the user with a list of subjects - those that need special set ups. If you're taking electronics, then install X application. If you're taking music, install Y application. Almost like getting a textbook list. But then, coupling that with package management, you could also do bookmarks. This of course lead me to write some rudimentary flow control (though I've got to rewrite it when I have a chance to be slightly less rudimentary).
Flexibility leads to more flexibility - but then, flexibility doesn't really come until you find a need for it. It's one of those things that's really hard to anticipate. Sure, there are a few basic little rules you can follow :-
- Make your application modular. Having loads of small bits of code around is far easier than trawling through a bit block of code. Especially things like those conditional tests you seem to do throughout the code. If those conditions ever change, it's easier to change it once...
- Avoid "magic numbers" - use constants instead. An application makes a whole lot more sense when the numbers mean something.
- Use constants for strings (where appropriate). It cleans up the code and allows you to alter those strings in one place rather than trying to trawl through the code. I've never done internationalization but I imagine having constants makes this all a little bit easier (scalability).
Of course, these guidelines miss the brilliance that every piece of software should have - and funnily enough, it's that same brilliance that kills a certain amount of portability.
I was having a conversation with someone about badly written code. Open Source software, while I'm a huge fan, does have a fallacy. Not a fallacy exactly - more a... misinterpretation? Code should be reused. Which is true - but only where appropriate. I'm of the opinion that code should only be reused if it matches up to the concerns/specifications that you're trying to use it for. Those bits of flexibility that make a piece of software awesome for a particular purpose can have the effect that it overcomplicates or rules out certain purposes for a piece of code.
Reuse of the same code base can also limit diversity. Take GIMP for example. GIMP is a fantastic program which, for most home user's purposes, can easily take the place of Photoshop. However, for a long time, it was THE only real option for image manipulation on Linux. The lack of diversity means that, in my opinion at least, image manipulation in Linux stalled. It's direction was dictated by a single project and while that project really is awesome, other ways of doing things were dismissed. In fact, GIMP is one of those projects like OpenOffice. For the most part playing catch up with proprietary solutions - essentially dictating it's direction and it's architecture. While parts of the code should be reused, it's suitability for projects like Krita, while very similar, have very different concerns.
It's all an engineering problem. Trying to balance out the awesomeness (flexibility) with reuse (portability)...