My name is Christopher Bojarski. I'm a web developer, programmer and blogger. Fan of all things technology related. Avid reader and traveler. Married and living in Philadelphia. Connect with me at cbojar.net.
Magic numbers are considered such a scourge upon code bases that there tools out there to automatically find them and root them out. After all, who knows what setValue(6); really means? There are also many approaches to giving better names to magic numbers. Not all of them are good, though. For example, we have a callback that sets a completion percentage on a status: void callback(Status status) { status.updateProgress(0, "Starting"); // Do some stuff... status.updateProgress(25, "Some stuff done"); // Do some more stuff status.updateProgress(50, "More stuff done"); // Reticulating splines status.updateProgress(75, "Splines reticulated"); // Validate everything status.updateProgress(100, "Complete"); } Those percentages would get flagged as magic numbers by the automatic tools. The developer would need to extract those out to constants to make that tool happy. A thoughtful developer would create
Developers of all experience levels commonly share a false belief: more typing means more complexity. The most powerful idioms and tools often require a few extra keystrokes, but dramatically reduce complexity. The final keyword in Java is a bit of extra typing. The final keyword can be applied to variables, method parameters, instance members, static members, methods, and classes. By making these final, their values will not depend on their context. They will be known constants through their lifetime. Their constancy removes a large cognitive load. The developer no longer needs to worry if the value was not set or if it was set multiple times. Many developers forgo this benefits to avoid typing the extra keyword, to their own detriment. Later, they spend too much time chasing down defects caused by mutable state. Developers will often shun creating small types and interfaces because of the extra typing involved. Interfaces can abstract away many different implementations behind
There is code out there that is ugly. I mean really ugly. I know, can you believe it? But it's true. One such example of really ugly code is code that has lots of deeply nested calls. The tests are trying to test a dozen different methods in every case. The methods look so simple with just a few lines and a few calls. And then those methods called have a few lines and a few calls. And then again, a dozen or more different calls deep. We want to use private helper methods to make our code clearer and cleaner. Calling methods is also largely what programming is about. But sometimes we overdo it. Deep call hierarchies are difficult to follow and they can mask what the code is really doing. Each call means that we have to look all over a class to see what actually happens. This makes debugging hard. This makes testing even harder. Say we have the following code: class DataLoader { void loadNationalData(Nation nation, int year, DataReader reader) { for (State state