« When you die, will it matter? | Making Your App Infintely More Testable » |
“Using singletons is bad. Don’t do it, ever.”
“Don’t micro optimize your code! It’s pointless!”
“Don’t worry about performance until you have performance problems.”
“100% code coverage is necessary for your unit tests.”
“No optimization without benchmarking first!”
We’ve all said these things at some time or another to a junior developer that we were helping, teaching or mentoring. Their question usually relates to some work that they are doing or an issue they’re trying to understand. For the sake of simplicity, we make a blanket statement, assuming it will be enough to cover us and obtain the desired outcome.
But are we doing the developer we’re helping a disservice?
Amy Stephen tweeted the following on Twitter:
I tweeted back at her:
And she said:
This got me thinking about the way I write blog posts, and how we as a developer community teach the more junior developers among us.
Amy has a great point. Her point is that by using absolute statements (e.g. never, always, must), we potentially hurt the developers who are trying to learn.
There are few things that are absolute in programming (code that has a syntax error will never compile). But most things are far more nuanced than a simple “yes” or “no.”
For example, I’ve completed micro optimizations on code that would run thousands of times per minute to shave milliseconds off the process.
I’ve considered 80% code coverage to be acceptable on an application that was difficult if not impossible to completely test.
And I’ve optimized before I had performance problems, knowing that failure to do so would inevitably lead to performance problems later on.
These are all things that I’ve told people never to do, yet when the situation called for them they were, in fact, the right solution.
I believe that as developers we have an obligation to teach when a tool is bad, and when a tool is useful. Though many developer may never have an opportunity to actually need microoptimization, the fact that they might need it should be enough for us to detail the (very limited) circumstnaces when it can be useful.
Nuance in software development is a virtue, not a vice. And I intend to begin embracing it more and more as I write. Sure, it might make my articles longer. But it will also make them more useful. After all, my goal is to teach others what I’ve learned. And Amy is right: if I never show the right way, people will never know what it is when they need it.
Brandon Savage is the author of Mastering Object Oriented PHP and Practical Design Patterns in PHP
Posted on 4/5/2013 at 7:00 am
Hikari wrote at 4/11/2013 10:37 pm:
Interesting, I’ve been saying that a lot.
Patterns and rules were created to help us, to bring us the solution easier, quicker and more reliable. Not to lock and get us worried.
Focus on the objective. And of course always aim quality, reliability and maintainability.
Devon H. O'Dell (@dhobsd) wrote at 4/12/2013 9:32 am:
The danger of not writing in absolutes (especially when writing an article as an authority on a subject) is that one sounds unsure. If usage of these conditional modal verbs and adverbs becomes pervasive throughout an article, the audience is left wondering whether you actually know what you’re talking about. Of course, dangers exist when writing in absolutes, even outside of potentially confusing newbies. Pedants (like myself) like to point out the cases where the presented argument doesn’t apply and the writer is also left vulnerable to cases where stating an absolute is just wrong.
It’s easier to discuss a subject in absolute terms with people new to the subject matter than to an audience of diverse background. I agree this has the potential to stunt the newbie’s professional growth, but I’m not sure by how much. The problem is that speaking (or writing) about “exceptions to the rule” in-line tends to lead to derailment of the conversation. When talking about concurrent systems, processors, and non-blocking data structures (my current field of interest), you can spend literally hours answering the question “why is this memory barrier necessary” if you take all the detours. In these cases, it’s very difficult for someone new to retain all of the information, and the newbie can feel like they learned absolutely nothing.
Even though I work a lot with high performance systems these days, I still think that premature optimization can be bad. Fundamentally, you need to know the goals and constraints of the system you need to build. If you understand that a commonly used architecture can’t fit the desired performance goals, is it premature to optimize pieces of that architecture (perhaps by considering employing novel data structures from a research paper you just read)? Absolutely not. But the kind of person who is talking about using a hash table because it’s faster than a linked list when you are dealing with at most 5 objects needs to hear that as an absolute. At some point, if the person progresses in skill, they will learn naturally when those cases are wrong.
One that really pisses me off is “don’t use singletons.” When I ask why, it’s invariably because they are “hard to unit test” (as if unit testing is the only valid testing strategy ever devised). It is the logical access pattern for write-once, read-many objects. Without it, you have to do a lot of cloning (to get the same behavior), which is slow and expensive in memory. And when you get to a language like Java, where object creation is extremely expensive, singleton access patterns are a very valid way to decrease memory usage and increase speed. Someone going from PHP to Java who has heard “never use singletons” is going to hate Java because they subscribed to (quite frankly) bullshit information. (I would argue it’s also bad information for PHP, but whatever.)
I digress. Given my comment history on your blog and my admitted pedantry, I agree that it would be a good idea to embrace this idea. Even in this article, you state:
> There are few things that are absolute in programming (code that has a syntax error will never compile).
…this is true until the language’s syntax changes to allow the offending construct. (Go is an example of a language in which this case has happened multiple times in the past 5 years). Finding a balance between absolutism and conditions leading down a rabbit hole of tangents is key. Good luck!
Martin Hlaváč (@m_hlavac) wrote at 4/15/2013 11:42 am:
The problem with novice developers is that they need specific advice. If you leave them in a situation where they have to choose on their own they just don’t know how. That’s why absolutes are really needed. You could always say that you can do it this way which is the best in 99% cases but there will be someone who will learn the other way and use it absolutely stupidly.
With premature optimalization i found an interesting approach. Same as with CI where tests must pass to deploy the application i made test which tests how fast the application is. This way i can put some constraints just to keep the applications in some boundaries.
@Devon H. O’Dell: My main concern about singletons is how hard are they to change. If i create a singleton and a use it somewhere i can’t change singletons implementation. This leaves me with a deep coupling.
Even in PHP world i sometimes wonder if it’s better to create a object than put it into container and feed this object to other object via dependency injection. Especially when everything i use is only in my application that is not going to be opensource or altered at all. Problem is that every time i made a singleton it got somehow against me and sooner or later someone starts adding new methods to it which will create unreadable and unlogical code. Why? Because it was already there and that was the best place where one could put it.
Devon H. O'Dell (@dhobsd) wrote at 4/17/2013 10:20 am:
That sounds like more of an argument for having a good design than for avoiding use of singletons.
« When you die, will it matter? | Making Your App Infintely More Testable » |