Writing good code requires you to perform experiments
As an example, suppose you need to extract some information from a string and decide the best way is to use a regular expression. You know that the problem isn't trivial and that you probably need a few attempts to get it right. Still, your initial inclination is to just put the regex in there and go through the motions of compiling the code, performing the steps required to invoke the code (click a button, enter some text, etc), find out that the regex doesn't work, modify it and go through the motions again and again and again, probably while making some other modifications. Because the cycles take relatively long, progress is slow and you start cursing every typo. If you recognize this, then I think you can become faster and happier at your problem solving by reading on.
The advantage of the 'intuitive' approach is that, if the solution is right, you have immediately come closer to solving the larger problem. However, if the solution fails, the iterations to be informed of your failure and to verify subsequent modifications may soon take more time than developing a seperate solution to the subproblem would have taken. For some reason, we always seem to underestimate the amount of work it takes to get it right and consequently we opt for the small change that we will have the correct solution the first time around.
Some of you may now be thinking that the obvious solution is to write a proper unit test and run that unit test after every modification, until the code passes the test. I agree that goes a long way, but usually the test is part of a larger number of classes and running all those tests takes times, especially if it bootstraps an entire Spring-Hibernate application or something of the like. In such as case, it still takes more time than is needed.
My solution is not to be afraid to experiment. It seems to cost too much time to create a new script or class, seperate from the larger project, provide the correct libraries, run this small project multiple times to get feedback on your solution and finally copy-paste the solution back into the project your are working on. However, my experience is that it is well worth the time you need to do this, because it prevents the endless cycles of building-deploying the entire application and getting it to provide feedback. I hardly write a regular expression or SQL query without first testing it seperately from the application. Now these example are given at the smallest level, but it also holds for somewhat larger design issues and even for issues people call 'software architecture'.
Another thing about these small experiments that I find a major advantage, is that it gives you the freedom to explore some avenues that you wouldn't dare put into the actual project. You can't just start switching libraries or refactoring relatively large parts of the code and changing too much is risky and frowned upon, even if you can easily revert your changes (assuming you are using a versioning system. If you aren't, stop reading, install Subversion and commit your code before continuining this article).
A third advantage of experimenting is that it encourages you to rewrite and polish the code that you are writing. You can go through more iterations in experiments 'outside' of the project, because you have a clear overview over the code involved. Modifications of code inside a larger project are less inviting to proper refactoring to do 'the right thing'.
Painters, writers, craftsmen, even philosophers: if famous ones are asked for the secret of their succes, they always advise exercise and experimentation. I hope I have explained that it also simply makes sense. If you don't want to take it from them, take it from rationale.
First write a working piece of code that solves your problem, then do a complete rewrite. The second version of the code is almost always more elegant, better to understand and faster than the first draft.
Languages with an interactive interpreter are also a huge advantage when you want to play around or experiment with your code. No need to create boilerplate classes, compile etc. before you can even (re)run a single test on your code.
Just today I created a blank C# solution because I needed to implement a "Left()"-alike function from VB.Net. Just to make sure behaviour was the same I created a console-app, wrote my code, called the function with all possible 'edge cases' and 'monkey proofed' it and pasted the..what...6 lines of code back in the main project
Even though, I work with Visual Studio Team System now and must admit I am slowly drifting away from this path. Very slowly, but I am. That is because of the awesome test-projects with unit tests VS allows you to set up; this also saves you a lot of time creating blank/new projects and allows one to blackbox test every aspect of a function.
Despite what the name implies, the application allows you to test any amount of code, not just dlinq statements.
However, larger more high level parts of the applications I work on are generally tested first outside of the project because it's easier and faster to debug (due to low overhead).
The most recent example was a cooperative multi-tasking scheduler; due to the nature of the beast it was quite difficult to debug within the original project. Other examples include file parsers and fooling around with floating point notation to perform mip-map level selection.
Most of the time I just create a simple new project in my IDE which end up getting named 'Foo1', 'Foo2' et cetera. There are specific tools available to assist in these kinds of things such as RegexBuddy and SnippetCompiler. Other things are the command-line applications for your database, or simply the command-line regular expression tools such as sed/awk.
[Comment edited on Thursday 5 March 2009 15:28]
Experimentation requires a disciplined approach, where you change one thing at a time and then test it. That absolutely requires unit tests. And what's this garbage about unit tests requiring external frameworks? A unit test does not require any external frameworks. Any test that does is, by definition, not a unit test.
If your unit tests take too long to run, then they are worthless. Drop everything else and fix that first. If you don't, the dragon of complexity will overwhelm you sooner or later.
Your advice for using version control is a good one but the choice of version control is not.
Git is a better choice especially if you are developing individual pieces and integrating it with the rest of the code.
This might apply to a bunch of similar tools (with interactive and batch like mode). It does make a big difference against a complex setup like in only using a 'full' (code to .exe) compiler tool.
This makes my code great quality since I start... wanting to test a regular expression? No problem, use the interactive interpreter.
Want to test a module? No problem, run the module in 'stand alone', as main module, then then the 'if __name__ == '__main__' quick test code will test your functions.
In the end you have much added value from your experiments in the future, because as a test they verify the correctness of your changes. (My changes did not break anything else etc...)
search engine optimization az
Garrett Metal Detectors
Comments are closed