par·a·digm – example, pattern; especially : an outstandingly clear or typical example or archetype
There are many paradigm pitfalls that we, as developers/designers/analysts, fall into. The most common reason for our consistent trip-ups is the comfort we feel when using a concept we have successfully implemented before. Unfortunately, staying in our comfort zone stifles creativity and often leads to bad designs. Here are some paradigms and ways to recognize you are falling into them.
0, 1, or Many
Developers think in absolutes, in states, in binary. When a customer asks for a toggle button, we see 0 or 1. When they ask for 3 checkboxes, we can’t equate that to 0 or 1. And if the answer can’t be pinned down to 0 or 1, we can’t see the logic behind pinning it down to any finite set of choices. So, we dont see 0, 1, 2, or 3; we see 0, 1, or many.
This is an inherit problem in the developers’ mindset, pointed out to ignorant developer me by a colleague, Mike Arace. Part of our mantra as developers is to think ahead for code reuse and flexibility. If a customer thinks they need 3 choices, then they might need more later in the lifecycle. So we plan for it now.
Many times this forward thinking is premature. The flexible solution is almost always more complicated than the simple 3 choice solution. But it is also likely to be an incomplete solution when choices 4, 5, and 6 are added.
Worse, still, is that sidetracking oneself with future details detracts focus from the problem at hand. So, choices 1-3 are also likely to suffer.
And finally, the worst is that customers are able to pick up on when you are forcing future flexibility down their throats. They don’t like it and they will be frustrated by it. When you miss a deadline or go over budget, they will think about it. But most importantly, you and they both will not have your full attention on defining requirements for the here and now.
Avoid this by listening to your customers and their stories. Gather the requirements without thinking about the solutions. Wait until the design phase to figure out what should be considered for future flexibility, what parts are still to undefined, and what parts are so simple they can just be throw away in the future.
List, Detail, Edit, Save
Lots of administrative type applications follow this paradigm to the boring T.
I have a list of students. I want to see all of them. Then I want to drill down into one to edit their email. I want to save my changes and then go back to the list.
That is easy for a developer. And dull. Mind numbingly dull. But it is often easy to fall into the easy trap and fill the dull void with coffee. But who does that serve, beside the cute barista at Starbucks?
Break free of this paradigm with some Ajax goodness. I would turn that boring list of students into an editable table. The use could just click on the email column, make a change, then move on to the next student. Doesn’t that feel empowering to the customer and less dull for the developer?
The best way to recognize an opportunity to ditch this paradigm is to look for list screens that are just placeholders for a task list. Instead of burying the task (like changing email addresses) behind a detail screen, front load the task onto the task list. Other great examples of this are the mass delete functions in email programs, One-Click shopping, and the Netflix queue.
Form, Submit, Action
This one goes hand-in-carpal-tunnel-ridden-hand with “List, Detail, Edit, Save”. Since before the ancient time of VisualBasic forms, we have been developing data processing applications under this paradigm. User enters all their data. The submit it to us. We perform some actions on it. This is great for developers and terrible for users.
Users enter in the wrong data. They choose a username some else is already using. The fat-finger their zip code so it doesn’t match their state. And when they are done, they double-click the submit button.
Much like “List, Detail, Edit, Save”, this paradigm can be avoided using some nifty Ajax. The best approach is to think about what data you can actively validate. Usernames, is a good example. You know all of the usernames in your system. You can use a query to a web-service to validate data entered into the username textbox and tell your user if CoolGuy1981 is available.
The Customer is Always Right
This is a terrifying requirements phase paradigm. The customer, and her requests, are always right and exactly what she needs. Therefore, requirements, use cases, designs, and code are written to meet her needs exactly.
Unfortunately, no customer knows exactly what they need. They usually know most of what problems they need solved. It is the analysts (and developers) job to help them explore and determine root causes and tribal knowledge and political reasons for their problems.
If you are faced with implementing something you think is a bad solution or an interface with poor usability, discuss your concerns with your customer. Explain to them, technically if necessary, why you think a different solution is correct.
The Customer is Always Wrong
There is always a flip-side. I have encountered developers that are sure every customer and user is dumber than a box of rocks. That, of course, is not true. There will be times, though, with every customer where you are sure your idea is better and they are wrong.
When this happens, I like to turn to documentation. Find a document type that is intended to solve the type of problem you and your customer are in disagreement about. Go over how to use the document together so you are on the same neutral playing field. Then work together to document your problem and solution.
The act of removing your opinions and turf from the process will help you see eye-to-eye.
Premature Optimization
Fitting that this is at the end, I guess. I am sure that I have wasted a not-insignificant portion of my coding life tweaking queries for performance, factoring & refactoring algorithms, and pretending to fully comprehend big-O notation only to find out that I would be running my code on 47 load balance 8-core servers.
The moral of my story: Don’t waste your time optimizing code that isn’t written. Write code against your design and see what works. You should be able to recognize when you are writing bad, cumbersome code. (If you can’t read Code Complete) Refactor your design and code when you encounter problems. When you think it is finished and functionally sound, performance test it. You will be able to focus your efforts on fixing the areas truly susceptible to performance problems.
There are many other paradigms that are hard to avoid. When you feel yourself talking in only analogies or raised voices, you have probably fallen into one. Take a step back with your team and identify the pitfall. Develop a means for collectively avoiding it. The team will be more effective, and you will be happier at the end of the day.
