When your solution is a dud, you probably didn't talk to your users. When your project is successful, there's a fair chance you followed good design principles.
A few months into my first programming job, my team was assigned to assist another department with their modernization effort. Our goal: to minimize the number of manual steps in one of their core processes. Our initial approach was fraught with difficulty; we were purely programmers, unused to the task of end-to-end project planning. In fact, the first iteration was so bad that we scrapped fully two-thirds of it. Once we began talking to our users, however, we made real progress and unknowingly applied many of the lessons of design thinking.
Albert Einstein is often quoted as saying that if he had only an hour to save the world, he would spend the first 55 minutes defining the problem and only 5 coming up with a solution. In other words, you must fully understand the challenge before you attempt to tackle it. My team did the exact opposite. Owing to the separation between departments, the assignment was communicated via the management structure rather than face-to-face. During this game of organizational telephone, numerous details were lost, including key project requirements. Our first implementation was based on this incomplete information, and we spent weeks programming a solution to the wrong problem. Once we started a dialogue with our end users, though, the solution basically fell into our laps.
The two departments in question here had a difficult history. They had managed to work together thus fur by maintaining crisp boundaries and taking care not to step on one another's toes. Interpersonal interaction between low-level employees was minimal. My team, unfortunately, had a low estimation of our users' abilities, which this uncommunicative environment did little to dispel. As such, we designed a system that was far too simplistic for our customers. Once we began interacting with them regularly, we realized that they were much more sophisticated than we had given them credit for. They didn't like our rigid solution because it was not flexible enough for their varied use cases. Once we stepped back from our own point of view and acknowledged our biases, we were able to arrive at a more mature solution much more quickly.
My team had never heard the phrase "design thinking", but the process we used to craft our eventual solution was nearly identical to it. In a nutshell, the process is:
1. Talk to your users to understand their pain points and clearly define the problem.
2. Synthesize what they say and use it to define a possible solution.
3. Create a prototype.
4. Gather user feedback on your prototype.
5. Repeat steps 2-4 until your users are happy.
As mentioned earlier, the development of the initial product was done in a vacuum. At no point in development did we actually talk to the people who were going to be using our tool. We had fallen prey to the classic engineering mistake of assuming that a task clearly written is also correct. We assumed that, once we "knew" what the problem was, all we had to do to create value was to write code that followed the spec, so we spent several weeks getting a more-or-less useless product out the door. When we started talking to our users, though, it took us less than a day to get a usable prototype implemented. Once we had the prototype, we were able to test more-or-less continuously with our users, and the product evolved rapidly. Though its eventual direction was unanticipated, the final design was both simpler and more powerful than our original concept, and we were able to remove most of the original code. Had we not established a feedback loop with our users, the second iteration would likely have gone the way of the first, and they might still be struggling to use an ill-fitting tool.