Once upon a time (and isn't that how all good stories start?) I was managing a software team and we were working on several initiatives. Projects were assigned based on who was available, their skillsets, and their development goals. This resulted in two developers, let's call them Mary and Melissa, being assigned to the same project.
Mary and Melissa had been working together for a few weeks when I started hearing complaints in my one-on-ones with each of them about the other. Mary was complaining that Melissa was taking too long to do her part, and spending time on unit tests that did not make sense because things were in flux with the project. Meanwhile, Melissa was complaining that Mary wrote sloppy code and did not write enough tests (she even showed me comments in the code like "hack:...." and "to do: someone should add more error handling here"). Each of them had valid points and feedback for the other.
I spent the next few weeks coaching each of them on how to improve and address the other's concerns. With Mary I was focused on pushing her to write more tests and not just throw things together, and with Melissa I was focused on having her prototype something quickly and then add the polish after it was working. Both of them tried really hard, and both were miserable. It just was not what they were meant to do.
These two women were just not meant to collaborate. This got me thinking: how could we change the process so they both could write code the way they liked to create (and that catered to their strengths) and we could still meet our team objectives?
From this was born the v1/v2 development process.
You see, certain developers love building the first versions or prototyping—they are the ones who love hacking things together to get something working quickly. They love (and are best at) building version 1 of a product. The other type of developers love building the second version. They see their code as a craft and write unit tests for everything. "Test coverage" and "beautiful code" are phrases they use a lot.
And of course this definition is not black and white—there are people who fall on different sides of the line at different times, so it is more like a spectrum.
Typically, the v1 person does not like working with the v2 person, and vice versa—not for personal reasons, but because of the ways they think and create software. At the heart of it, the fundamental thing they enjoy about what they do is different.
By changing the way we thought about software, we were able to address this concern and actually make the team more agile and solve some business problems along the way.
When it comes to software development there are many ways to build and create products.
In my experience it is difficult to build the right product the first time. By "right" I do not just mean something customers will want and use, and that hopefully will generate revenue, but also the right technical solution. How customers will use products can be difficult to predict. For example, before you ship the first version of a product it can be difficult to answer questions like:
Even if you could reasonably answer these questions, or if you built a system that took all these things into account such that you could "just add hardware," the effort would probably be larger than if you had simply pushed to ship a first version quickly. And it is possible (if not always probable) such a system would be over-engineered (since it was designed to solve problems or scale in a way that may not be useful), or even have other unforeseen issues. While there are certainly pros to doing it right the first time, in practice it is very difficult to get it right, and building the end-all system will take longer, delaying the answers to all of the questions indicating you are moving in the right direction.
There is a popular movement called Lean Startup that advocates fast iteration and data collection to home in on the right product and requirements as quickly as possible. It is all about figuring out what customers will use and then building those things. These ideas can also be applied to the technical ways we build products.
Similar to creating a minimum viable product (MVP), build the minimum viable technical implementation that meets the business goals (meaning the product can meet current usage requirements and performance).
Most engineering teams have been taught to think about software design and architecture from the beginning and to build something that can scale. However, if you do not have any customers yet, scaling really is not your challenge. So in some ways, designing for scale when you do not have to scale yet is solving the wrong problem.
Of course I am not advocating doing something stupid, or writing bad code, but do not over-engineer or solve problems before you have them. Here are some examples:
All these shortcuts will help you get something out faster. They may not be best practices but they do ensure you are building the right thing.
In many ways, this process is about looking at the problems differently and, instead of solving the "big" problem, focusing on speed and efficiency—getting the highest ROI (return on investment) for your development resources.
So you modify your development process to ship the first version quickly, and then once v1 is out in the wild, plan to start on v2 right afterward.
Then your v2 can address all the problems with the first version of the product. You can improve usability, cut or add features based on customer usage and feedback, pick the right technology and libraries to power the product, and spend time writing acceptance tests and unit tests are unlikely to change. From a business perspective, you get the product out there faster, so it is easy to see if this product is going to drive revenue and success.
It reduces the risk of over-engineering. As noted earlier, getting something out quicker and understanding how it is used (or how successful it is in the market) will help confirm you are building the right product and solving the right technical problems for your business. This allows you to mitigate the risk of building or scaling out systems that may not address the production issues.
If you build the wrong thing you can correct it. Since the product is truly the minimum viable product, you reduce the risk of wasting resources creating the wrong product. Furthermore, you will get feedback earlier in the release cycle and can pivot or make changes faster (since it is always more difficult to change a system with a plethora of moving parts).
Chances are you will get to market faster. Building something quickly will help you launch sooner, which will help you test and determine the viability of your product faster than waiting for the bigger launch. This means you will not spend time building software your customers will not use or you cannot sell.
Staffing and personnel happiness. This is one of the biggest upsides to this method. Software engineers get to do what they love, in a way that caters to their strengths. Moreover, they are not forced to work with people who do not share their approach, and they do not have to work in a code base they cannot sculpt into their desired piece of art.
Total time to build is more than if you just got it right the first time. In this model it is likely v2 development will be finished later and the total development time will be greater than if you built the product once. If you build the v1 using one technology (say, a MySQL database that will not scale the way you need it to), and then the v2 needs a different one (say, a proper key value store for faster queries), the team will spend time shipping and building expertise on one database, only to have to learn and manage another.
Operations can be a headache. Most seasoned engineers will tell you that building something really fast can result in operations nightmares if the usage or data grows in a way that was not considered. No team likes being operational and fighting fires. Of course, if this is a problem it probably means your product has achieved some adoption and success, so at least you are solving something that produces real value. However, even for the v1 it is still worthwhile to identify risks and potential bottlenecks, so in the event there are problems the team will have some ideas for solutions.
Like any software process or methodology it is important to assess if this makes sense for your business, product, and company—it certainly is not a one-size-fits-all. However, it definitely has its merits, so feel free to steal the pieces you like.
If you do embark on this journey, here are some pointers from my experience:
Get management buy-in. This is really critical, because a key to this approach being successful is always building a v1 and a v2. If you do not have buy-in and your boss is content to keep and operate the v1, your team is going to hate you. Seriously. No one wants to get stuck supporting crufty v1 software indefinitely. So make sure everyone knows and understands the plan ahead of time.
Measure everything. In order to build the right v2 you need to know what to build. Where are your bottlenecks? How is the data growing? Without this data it is very difficult to realize many of the advantages of this model. Make sure you think about what you need to measure, and how you will measure it, before the product ships.
The v2 will take much longer than the v1. I have personally seen this process evolve across four projects (no, it is not a large sample set), and in each case the v2 took more than twice as long as the v1 to create and launch. Of course, every v2 I have launched had a lot of extra features, and they did not always leverage a lot of the v1 code. Some people assume the v2 will be faster, since "you have already built it once before," but I have not found this to be the case.
Have a tight feedback loop with your customers. Make sure it is easy to get insight into what people use, what they like, and what they do not like—that way you can build a great v2.
Make sure v1s and v2s are celebrated equally. Sometimes teams or companies celebrate the first launch of a feature in a much grander way than the next version. But in this case the next version is what you need to grow your business. It is just as important as v1, if not more so. Make sure you value each of these equally, or people will gravitate to the project with the most fanfare, not necessarily the one suited to their strengths and talents.
Be open to people being good at both v1s and v2s. Sometimes I think I have someone pegged and then they prove me wrong. Be open to the fact there are not two types of people, and some people are just good at everything. (I just wish I was one of those people!)
I hope some of these ideas will prove useful for you and your team. If anything, let this anecdote inspire you to question the way you are doing things, and look critically at innovative ways to improve how you build software.
Related articles
on queue.acm.org
A Conversation with Tim Bray
http://queue.acm.org/detail.cfm?id=1046941
Big Games, Small Screens
Mark Callow, Paul Beardow, and David Brittain
http://queue.acm.org/detail.cfm?id=1331296
Major-league SEMAT - Why Should an Executive Care?
Ivar Jacobson, Pan-Wei Ng, Ian Spence, and Paul E. McMahon
http://queue.acm.org/detail.cfm?id=2590809
©2015 ACM 0001-0782/15/12
Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and full citation on the first page. Copyright for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, or to redistribute to lists, requires prior specific permission and/or fee. Request permission to publish from [email protected] or fax (212) 869-0481.
The Digital Library is published by the Association for Computing Machinery. Copyright © 2015 ACM, Inc.
No entries found