As a software developer, I’ve noticed that experienced developers will often start the answer a question directed at them with “It depends.”
“Should I use inheritance or composition?”
“It depends. Usually composition is better, but it’s not always the best solution. If you have a stable, common abstraction and it’s easy to extend the base class, inheritance may be better than composition.”
“If I want to learn programming, which language should I start out with?”
This may seem obvious but I believe, especially after reading about the Dreyfus model, this habit of saying “It depends” when faced with a particular situation comes from gaining significant experience in software development.
I recently read about the Dreyfus model of skill acquisition in the book Pragmatic Thinking and Learning by Andy Hunt. It models how one goes about attaining and mastering skills. In the model, there are five stages of skill acquisition:
1) Novice 2) Advanced beginner 3) Competent 4) Proficient 5) Expert
Let’s look at each of the stages:
Novices usually are more concerned with accomplishing a task than learning. They just want to get something done. They also don’t have much or any prior experience to help them; they don’t have any knowledge they can make use of in order to know that “When X happens, do Y.” This means that when they make a mistake, it can be very troublesome. Because of this, novices need to follow recipes, sets of context-free rules.
A good example of this is when grandma, who isn’t very good with computers, asks you for help. Grandma says, “My computer is so slow!” You might tell her to restart the computer, which solves the problem. Grandma, who is a novice at computer usage, doesn’t know that her computer is slow because she has 15 applications open and that closing some of those programs to free up resources would solve the problem. To her, she just knows “restarting computer = problem solved”.
But what if the context changes? Maybe grandma has a dial-up connection and is trying to go to www.mygrannybakery.com, which has a lot of images on the their main page. This results in a large amount of data going over her 56k connection, appearing slow to grandma. Well, restarting the computer worked the last time the computer was slow, so why wouldn’t it here? This is an example of where strictly following recipes fails because the context changes. Following these rules will help only to a certain extent.
Advanced beginners can start to do some tasks on their own without the aid of recipes, but they still have difficulty troubleshooting when unexpected problems occur. They have more experience than a novice to make use of, but the experience needs to be recent and similar to a problem they’re facing now in order to make use of it effectively. They still don’t have a holistic (big picture) understanding of things.
If you are interested in reading more about this stage, I highly recommend Erik Dietrich’s series of articles on this subject.
Competents are able to troubleshoot on their own, figuring out problems they’ve never seen before. They still have difficulty with which details to focus on when solving a problem, which can be solved with more experience, but they’re able to mentor novices and don’t need a lot of hand-holding from experts.
At the proficient stage, practitioners are able to do a very important skill: self-correct bad behavior. They can self-reflect and analyze how to do better next time. They’re also able to learn from the experience of others. Proficients also understand the big picture.
In my opinion, this is the point where developers start to say “It depends” when asked how to solve a particular problem. This is because, at this stage, practitioners are able to understand and apply maxims: proverbial, fundamental truths that can be applied to the current situation. Maxims are different from recipes in that they are not universal, they need to be applied within a certain context.
For example, look at the maxim “remove duplication in your code.” A novice may interpret this as a recipe and remove ALL duplication in their code. This may lead to some bad abstractions, as discussed in this article by Sandi Metz. Because the proficient has experience, they’re able to to see how a given maxim will work out in a given context. In context A, removing duplication will make the code more readable with no negative side effects whereas in context B, removing duplication will form a bad abstraction that others coming into the code will see and possibly build upon further.
Experts are primary sources of knowledge in a given field. They’re always looking for ways to improve. They have a lot of experience they can make use of to make the right decisions in the right context. Because of their vast experience, they know how to distinguish important details from irrelevant ones, if even on a subconscious level. A decision to do something can “feel right” even if the expert cannot explain why. This can be due to a combination of past experiences subconsciously influencing their way of thinking.
So yeah, the general theme here seems to be that as you gain experience, you can look at past experiences and apply those to the current problems you’re facing. As you learn more, you’re able to troubleshoot problems on your own and take given actions in given contexts.
What should you do in a given situation? It depends.