It’s excruciatingly boring to write specifications. It seems like it’s the most boring thing in the world that a product owner has to do. This could be the reason why most specifications are horrible and come across as the root cause of delays, reworks, and bugs.
This problem can be partly alleviated if a product owner is always available to talk to, but even that is not a cure-it-all remedy.
The agile movement has its peculiar point of view on specifications. The most extreme part of agilists express their feelings quite clearly:
There are two extreme views on requirements documentation (most use user stories to describe requirements these days):
User story is just an invitation to communication. It should be very short.
We should document requirements fully, with all known details.
Most likely, you accept option 1 and reject option 2. If you ask me, what option I prefer, I will answer “both”. Hold on your tomatoes and read on.
Let’s say, you start a project and have a backlog with 100 user stories. This is the stage where you should keep user stories descriptions short. Don’t waste time, many of these stories will never make it into production, they will die.
You pick a user story and ready to start development. At this moment you have a solution and this solution should be documented. Short description is not enough, since some details may be lost and implemented incorrectly, this will lead to re-work and time waste. At this stage you shouldn’t worry that detailed description of a user story is a waste, this story is going to development phase anyway.
Simply speaking, each user story has a life-cycle: Birth → Solution → Implementation → Release. Let’s review it:
Someone has an idea and user story is added into a backlog. Just a short description is fine in this case.
There are various methods to create a solution for the problem that user story describes. Maybe you have a special UX phase and special UX teams that brainstorm possible solutions. Maybe you discuss and invent solution in development team just before implementation. Maybe Product Owner creates a solution alone (worst case). Still somehow you have a solution.
Then you should document the solution with quite many details to make sure that solution will not be misinterpreted. Here you will argue that live communication is better than specification. I agree and will follow on below, but if you have a gap between Solution and Implementation phases (which is often the case), you have a good chance to forget many things about the solution. You will end up with sub-cycle: Forget → Remember → Lost Some Details → Re-Work. This sub-cycle generates nothing but waste.
Implementation may take several hours, or may take several weeks (happens). If a solution was invented outside a development team, it’s extremely important to have a kick-start meeting, discuss the solution again and find all weaknesses in it. It may happen that solution is unideal and can be improved. Kick-start meeting brings everyone on the same page and every team member understands how it should work.
Right after the kick-start meeting user story should have as much details as possible, including positive and negative flows, texts and labels, final design, etc. Memory is a good thing, but it fails quite often. Don’t rely on your own memory and on memory of other people, put everything you know into text and images.
When user story is done, there is not much value in documentation. If there are some minor discrepancies — that is not a problem. Sure, it can be used as a reference for technical writer, for example, so, depending on your context, you may want to have it corrected.
The main idea is that importance of documentation is low initially, highest in the implementation phase and falls down again after the release. Full documentation just in time is a good practice.
You may worry that it sounds heavy, but in real life a user story can pass all these phases in a single day. For such quick stories full documentation looks like an overhead, but usually it’s very short as well and may take 10 minutes to write.
I personally like when user story is fully documented (at the right time!) with all important cases, has final design attached, has all labels nailed and provides a good vision about the solution.
With many user stories you have rolling waves. Like that:
Now fish out your tomatoes and throw as many as you want.
How to use ideas from the great book by Daniel Kahneman Thinking, Fast and Slow.
Recently I read a fascinating book by Daniel Kahneman Thinking, Fast and Slow. It has tons of insights. Every chapter was a discovery. I learned so many new things.
I work in a software development company. It’s quite natural to apply new learned things to your domain. That’s what I’m doing in this post.
System 1 and System 2
The book is about two systems in the human brain. System 1 is fast, intuitive, alert and cheap. System 2 is lazy, analytical and expensive. Most daily activities and tasks are solved by System 1, while the most complex tasks are redirected to System 2.
When you use System 1 you feel nothing. It’s natural and effortless. When you use System 2, you feel strain and pressure. You notice that you are really thinking hard. System 2 is effortful.
There are many experiments that proves existence of these two systems. Make no mistake, there is no clear separation of these systems on a physical brain structure, but they describe how people think and make decisions.
If you are a software engineer, you’ll immediately grasp the nature of System 1 and System 2. System 1 is quite similar to cache, while System 2 is a business layer. Cache is cheap and fast, business opearation is slow and expensive.
Now I’ll take first concepts from the book and find examples in software development.
What You See Is All There Is (WYSIATI)
People usually don’t think about things they don’t see (in a broad sense). If you have some information, it’s unlikely that you’ll immediately question it and go look for some alternatives. Quite often people make decisions based on existing facts and limited evidence. This leads to several biases:
Estimation is not easy in software development. We make huge mistakes all the time. Estimation is a distribution.
Software estimation is the area where overconfidence flourishes.
“We need twitter integration — you ask — We want to accumulate all tweets with specific tags. When you can complete this?” Developers often don’t ask additional questions and just provide quick estimate like, well, 2 days. This is System 1 in action. It’s extremely unlikely the answer is correct. Lack of information somehow doesn’t impede immediate estimate. Developers should be smart and confident, oh yes! But also they should escape WYSIATI and think carefully about unknowns.
Problem wording does matter. If you describe the same problem using different words you can have different solutions or preferences. Consider two questions:
“Do you think we need a very experienced developer to solve this simple problem?”
“Do you think we need a very experienced developer to solve this complex problem?”
The question set the frame. It’s hard to answer “Yes” to the first question, it’s easy to answer “Yes” to the second one.
Some events are more likely than others. However, people have no good intuition about statistics.
Let’s say, you create a product that used by 1000 companies. You receive an email from a customer who think that his idea is really “must have” and should be implemented ASAP. The argumentation is perfect and does make real sense. You feel his pain and push this new feature to production with all your force. Well, you missed one thing: it may very well happen that 999 other customers have no need in this solution. You forget that customers base is large and a single request should be reviewed from that perspective.
It’s a very common mistake and I repeated it again and again myself. Now I know better and think very carefully about every request. No rush. In rush you delegate the decision to System 1, and this system do you no good in such a complex domain.
Answering an easier question
When we encounter a hard question, we tend to replace it in our mind with an easy one, that System 1 can handle. Here is an example.
You hear the question “How good will be progress on this project 3 months from now?” You replace this tricky question with “How good is progress right now?”
By doing this substitution, you don’t awake your lazy System 2 and allow System 1 to answer the easier question. We follow the path of least effort. The funny thing is that we don’t realize the substitution, we really think we answered the hard question!
If we like something or dislike something it affects our decisions greatly. For example, if you like node.js, you will be optimistic about choosing node.js for the new web application. If you hate node.js, you will provide so many arguments against it and will fight to death to apply another technology.
The affect heuristic is hard to overcome. People are not so rational, but clearly some reasonable comparison of technologies will be much better than a quick choice based on intuitive preferences.
I just scratches the surface, but it’s already obvious that our decisions in software development based on many biases and bad heuristics. What can we do about it?
Intuition vs. Models
Kahneman was very skeptical about our abilities to wake up System 2 when it’s really needed. Indeed, how can we change a human nature?
However, it seems we can do something. We can apply models.
Kano Model is a good example. It helps to make more intelligent decisions about new features.
Model is almost always better than intuition. Even a very simple linear model is better than most (all?) experts in a domain. Model forces you to think about the domain, about various facets of the problem, look at it from different angles — use System 2.
Here is the simple question: What feature should we start next? You can rely on your intuition and say “Advanced Search”. It may happen that this feature is not so important and there are dozen of more important features. You can build a simple model and evaluate your backlog. For example, the model can have parameters like:
Kano model (basic, delighter, performance)
Votes: How many customers and leads requested it
Frequency: how often people will use this feature.
Spread: how many people will use the feature.
Effort (S, M, L, XL, …)
Complexity. Will it increase usage complexity
With this simple model you’ll make much better decision for sure.
I believe models can be applied to many areas in software development. Decision making and problem solving should rarely rely on intuition, unless you are Steve Jobs.
There’s more and more buzz around estimates and #noestimates in software development. People like to write bold statements and go extreme about things in blogs. Usually, personal dialogues are much more balanced. Some hate estimates and believe it’s a useless activity. Some defend it with arguments of arguable truth.
I want to dig into intrinsic estimates complications, what people mean by “estimate” and what future directions we may attack → Read the article.
A couple of years ago I bought BMW 530 E39. Not that I’d been into BMWs all that much, but I just stumbled upon a good deal to replace my old car, and I went for it.
This car was excellent. I liked almost everything about it except:
The rain sensor. Even when set on the “High” speed it functioned very slowly, which rendered it mostly useless in the field conditions.
The front and rear windshield defogger/defroster controls. Too far to reach.
The weird audio set controls. I had quite some trouble getting used to them.
Setting the in-cabin temperature with up and down arrows.
Then I bought the next-generation BMW E60.
Now, what do you think?
The rain sensor works perfectly.
They made the defogger/defroster controls bigger and put them to the center.
The audio set started to make sense.
They have knobs for the in-cabin temperature, and it’s just a pleasure to use them.
The smart BMW guys resolved all the issues I’ve been uncomfortable about. But — of course — they added a couple of new issues instead:
In the E39, cruise control was located right on the steering wheel, and it worked just OK. In the newer E60 model they did it as a lame lever on the lower left side of the steering wheel, with absolutely non-intuitive movements to switch on/off and adjust cruising speed.
Door locks and hazard warning flasher switch were moved from beneath the driver’s right hand to the central console. For several months I’d start in the wrong direction to open the doors, until I got used to the new setup.
While the change #2 looks quite logical as it comes along with the new iDrive system, they have no mercy from me for the cruise control.
On the whole, the next-generation BMW remained the same, but better. I think that’s a very important principle for the evolution of any interface:
Same But Better
We’re getting at the good old issue of UI novelties here. What’s better, slowly and meticulously improve the current system? Or introduce new elements in radical spurts, leaving no stone unturned in the old system?
Users are quite inconsistent creatures. For one thing, they like to download updates hoping they’d finally get the features and improvements they’ve been waiting for. On the other hand, they hate getting used to new features.
Any interface develops in cycles. Someone comes up with a new interface, users start bringing in their feedback — that’s the stage of step-by-step improvements. One has to rework some parts of the functionality and mix in new features gradually, without having people learn from scratch.
Then, a critical mass of new knowledge is acquired over time, and if this knowledge is used wisely, it becomes clear how to improve the system along with the UI. That’s the time for revolutionary changes, and that’s how all interfaces develop (if they don’t die before their time):
Most people like short things: short tasks, short emails, learn-how-to-program-java-in-24-hours books, lose-weight-in-a-month video guides. Modern society is cursed by impatience and time pressure. Information flows hit us from all sides and we just can’t resist. We spend more and more time on shorter and shorter things.
Software development demands focus. You can’t create anything significant hopping from one thing to another. That is obvious. Less obvious is that product development demands patience.
Service development is different. In most cases you have a project with a visible end. It may be a year long, or even several years long. But still project will be completed someday… Or abandoned. Most service products are sprints. Clients pay you money and they want to have something as soon as possible. They radiate the impatience. They set deadlines. They resist to invest much into good engineering practices like automated tests. Yes, you negotiate all that and sometime with a success, but still it’s quite hard to sell a great development process to the customer. So you rush, cut corners, drop some good practices to save time and argue about change requests. Agile approach helps to solve some of these problems, but you still feel the constant pressure. And rush anyway.
This strategy doesn’t work for product development. It takes a decade or more to create a truly remarkable product. Constant rework, constant improvements, constant polishing and learning. You fail, learn something new, improve things and move forward. It just can’t be done without patience.
Suddenly you understand that great thing takes time and it changes your attitude. You learn how to run with a steady pace, maintain energy level and endure the race. In a sprint you have no room for any mistake. Even a little mistake will cost you huge. In a marathon you have time to fix problems and still win.
If you are in a product development business, I can give you several advices:
Learn how to learn. This road takes many years, you need knowledge to solve problems and invent things.
Learn how to wait. It is so fucking hard to me. Sometime I feel enormous pressure to speed everything up and run at a full speed. But I realize that it will drain all our energy and development team will be exhausted and washed out. We’ll start to lose people. Morale will go down. That’s not a viable strategy.
Embrace re-work. Most likely you will have to re-write some parts of the system 3-7 times in the next several years. You should be ready to do that. Re-work is good. It makes things better.
Ship early. You may think that now I’m a 100% perfectionist who will kill for the 1px design mismatch in a latest release. That is far from true. I like to ship things as early as possible to some closed group of customers at least. For example, we are working on v.3 of our product during the last 15 months. It is still not public. However, we had first users 9 months ago. Currently around 600 people from 100 companies are using v.3, we have constant feedback and make improvements based on it.
Remember, that most people can run a 100 m distance, few people can run a marathon.
Why it is bad to have a single point of failure in a product and what to do about it.
Every day we solve problems. Some people solve many problems, some few. Most likely in your project there is a person, who solves most of the problems. Sometimes it’s a Business Analyst, sometimes it’s a Designer, most often it’s a Product Owner. He knows the market, the domain, the customers, the competitors, the features. He knows how things should work and pushes his solutions hard. Usually the team can’t resist and just accepts this situation. Is it good? Can we find better ways? Well, we’ll have to have quite a lengthy journey to find out.
Setting the Stage
Imagine, you have a new feature in the backlog. At this point we have several potential scenarios with a different level of harm:
Leave everything up to the developer.
Discuss this user story just before the implementation, come up with a solution and do no specs. Make all the decisions on the fly.
Discuss this user story just before the implementation, come up with a solution and do the specs.
Assign user story to a Product Owner, let him come up with a solution and have him do the specs.
Have UX phase, brainstorm a solution and create the specs just on time, before the development starts.
You can see that some of the scenarios are good, some are bad, and a few of them are just horrible.
To create a perfect solution, we should answer the three simple questions: When? Who? How? Well, the most important question is Why? We’ll assume it’s already been answered.
Each story has its own life-cycle. It is born, it lives and then dies. There are three important moments in the life of a feature:
Someone has a good idea, and a feature is created in the backlog.
User story is released to production.
When is it a good time to have the complete solution? Obviously, not right after the story is created, as things change, and it may happen that this user story is no longer required. It may just be deleted from the backlog in the future. Somewhere in the middle when we have more data? Maybe, but still not perfect. The perfect match is when we have the solution right before the development is about to start.
In this case the solution is fresh and shiny. Everyone in charge does remember why things should work exactly the way described in the specs. It is certain that the user story will actually be implemented, so the solution and the time spent on it will not be thrown away.
If a feature looks very simple, the UX phase can start about one week before the implementation. If a feature is complex, several months may be a good timeframe.
Many teams rely on the Product Owner, Business Analyst, etc. and expect solutions and specs from them. A team doesn’t care about the solution, but does care about completeness of the specification. Sometimes this works, in most cases — not.
Some teams rely on communication and do not create specs at all. They brainstorm a solution on the fly and then jump to coding. Sometimes this works, in most cases… well, you got it.
Some clever teams rely on the group of people that consists of developers, testers, designers and product owners who brainstorm the solution, find the best one, iterate and delegate writing specs to the product owner. And these teams rock.
Why the first two cases are bad?
Yes, Product Owner is responsible for the product. Yes, he knows a lot. Yes, he can solve problems. And, yes, you expect too much of him. It is quite unusual to expect the best solution from a single person. It is always better to have a small group of people with various skills, various background, various focuses to find a great solution.
Product Owner can brainstorm everything alone and write all the specifications. He can haul the product alone. As a result, he would be a single point of failure… while there are many other buses in the streets.
The communication would be one-way, without much collaboration, and in such environment Product Owner would tend to ignore the opinions of other team members, since they do not participate in problem solving. If you don’t participate, why the freaking hell should I care about your opinion?
Knowledge sharing would be zero. Product Owner is a domain expert, he knows a lot. But the team gets zilch from his experience. There are no discussions, no collaboration, no two-way communication flows.
I used to be such a person. It was not good for the company.
Product Owner’s Rule #1: Don’t do everything alone
Got a real problem? Get together, brainstorm it quickly, get shit done and kick it out of the door. Sounds good? Hell, no. The good thing is that you don’t waste time and rush straight ahead. The bad thing is that the solution would be great rarely, good sometimes, and in most cases just average.
In the rush mode you tend to cut corners, take the first acceptable solution and go for it. There are situations when it is good. In any emergency case this is a viable strategy, but in the long run it will not work. Rush mode is very dangerous. You may be even proud of it and call it “agile”, but it is not.
— OK, the quick add feature. Who’s got any ideas?
— Well, let’s just put up the Add Task link . You click it and see the input field with the Name label and Save button. You add one task and see the input field again, so you can add many tasks quickly.
— Great! Let’s do that right away.
Maybe this is somewhat stretched, but in reality I saw very similar situations (and did very similar things myself!).
Product Owner’s Rule #2: No rush
I bet you expect a viable solution now. Here is the algorithm:
Brainstorm every feature in a small group of 4-7 people. Invite developers, invite testers, invite designers, invite product specialists. Invite everyone who has diverse skills and can contribute to a discussion.
Think. Talk. Draw sketches. Learn some techniques like Design Studio. Do use them. Draw sketches.
Build trust. Support honesty. Ban sarcasm. People should trust one another, or you will have a bunch of gamblers instead of a team. Don’t be afraid to criticize bad ideas. The people who can’t stand some reasonable criticism should leave.
Repeat. Several times for each feature. Mix people. Invite new people.
Eventually, several teams will emerge, the teams that can solve problems without you.
Find people that can lead features and be responsible for the solutions. Let them lead UX sessions and play the Feature Owner role.
Create beautiful specifications (this is where I really suck).
It took me 7 years to come up with this solution. It works.
Product Owner’s Rule #3: Spread the knowledge, use diversity, delegate
The “how” question is very broad. How to form teams? How to find solutions? How to evaluate them? How to document solutions? I’m going to just scratch the surface here.
Creative processes are hard to structure and hard to estimate. In general you don’t know when you’ll have a great solution. It may take several days or several years.
Each Feature Team has its own UX phase. Some people like to think alone, have decent preparations and then share ideas. Some people like to brainstorm things ad-hoc. Some like to sketch a lot. Some like to create paper prototypes. In general, it does not matter which practices and tools people use. The must have rules are:
Diversity. Team should consist of diverse people.
Iterations. First solution is not always the best. Neither second, nor third.
Feedback. Team should share potential solutions with other people and with customers if possible (and listen to their feedback).
There are many practices and tools you can try. I’ll just list some of them here:
DesignStudio. In a nutshell, you have a group of people. These people can split into teams or work alone. They have limited time to sketch the solution and then present the solution to everyone. Solutions are criticized. Then you iterate based on the feedback and sketch again. We’ve been using this approach with good results. Yes, it is time consuming. However, time is not important when you want to spread the knowledge. So use Design Studio in the early stages of people involvement into the solution phase.
Sketches. The ultimate tool to brainstorm, explain, evaluate and present ideas. The main advice I can give is: hide your “OMG I can’t draw!” fear and sketch a lot. You will get better eventually. Sketch + speech is so powerful, so fast, so cool. You can iterate really quickly, try a dozen approaches and skip bad solutions.
Critique. Do it. Express your opinion openly and politely. Don’t hesitate to upset someone. You solve problems here. Bad solutions should be thrown away. If you’re afraid to say something critical about your boss’ solution — it’s a bad sign. Fuck the common brainstorming rule about ideas and critique separation. This is only needed if you don’t trust each other. Trust gives you freedom of speech. Use it appropriately.
Diversity. It really works. There are many proofs and observations on how diverse teams outperform experts and solid “think-alike” teams. Try it.
Paper prototypes. Not as fast as sketches, but still good. With paper prototypes you can evaluate flows and find bottlenecks. It’s easy to grab them and ask some teammates to try something. You can even shoot a video and share it with people.
Usability Tests. We do them on a real application now. About 10 tests give a ton of feedback.
Product Owner’s Rule #4: Learn and try new things
The output of the UX phase is quite simple: feature specification. How to create beautiful specifications? We’ll talk about that in the next article with an intriguing title “Visual Specifications”.
Then, we became set apart from each other: here’s the JS team, and they give zero consideration to the server-side tasks. These guys are .NET guys, and God forbid if they lay their hands on the client-side (with rare exceptions). This distinction projects into hiring as well: here’s a .NET, a .JS and an iOS position. It manifested itself in particular as we got down to tp3, putting the clear boundaries between various areas of responsibility. The UI is done in .JS and .JS only, everything communicates with REST API, the core team negotiates the query/response format with the .JS team, and off we go. This is a nice way to start a new project. Each team is busy with their part: they design architecture and do the refactoring as they aspire to perfection within their boundaries.
However, there comes a time when the teams are almost done with the architecture, but there’s a flurry of horizontal application-specific issues. It somehow turns out that there’re tons of the UI related tasks, and few server-side tasks. That’s when specialization delivers the heaviest blow. The teams are not aligned, there’re twice as less developers in the UI team as compared to the .NET team. As a result, a half of the core team developers hang around nagging for new tasks, and one has to assign them to not so important jobs. On the contrary, the UI team is permanently slammed.
My opinion is simple: there’s no ultimate specialization. Sure thing, someone prefers one technology over another, and works with it most of the time. But a classy developer is able to adapt to a new ecosystem quickly and write in any programming language efficiently enough. The 80/20 rule of thumb might well be in effect here. You’re focused on your core competencies, at the same time reaching out to the new areas.
From the company’s standpoint, it’s very cool when someone can create a feature in its entirety. There’re less delays, the feature passes all the developments stages faster, there’re less discussions and handovers. One can truly stay focused on the tasks that are important at this very moment, and not shop for some work of a lower priority.
From the developer’s standpoint, it’s not as simple as that. I’ve never had any problems or issues doing something by myself. For some reasons, it is a big problem for some people. Yes, at the beginning you’re not likely to come up with perfect solutions. Yes, there will be some naive mistakes. But, in my opinion, a great software developer can deliver sensible solutions even in a fairly unknown environment.
Next, it’s about personal involvement. Many people hold .JS for HELL. However, if the framework is done, as well as HTML, it doesn’t look that bad. Some interesting things can be accomplished with .JS as well.
Why I liked to do a feature all by myself? It’s about the great feeling that I did it on my own, that’s why. This feeling means a lot to me. How about you?
To sum up, we will now resume hiring classy software developers, the ones that can create the entire feature from start to end, despite the technologies, and have nothing against that.
Office space is something many companies don’t get.
Sure, you should have a wide table, a comfortable chair and a fast workstation. But that is not the goal of the modern office. You can have this all at home. The real goal of the office is to enforce communication. Creative work doesn’t happen at your desk, as you should already know.
A good office setup enforces communication. It has many places where people can sit and chat. It has many whiteboards and cork-boards. It has comfortable meeting rooms, a kitchen, a shower, coffee machines, a bar and a sports room. You are here to meet people and to talk to them face-to-face.
Traditional office kills creativity.
Our new office is different. It is designed to help people meet and talk.