Have you ever been working through a problem only to hit a roadblock that leaves you stuck, not knowing what to do next?
Chances are, if you are like most programmers, you took a moment to check your Facebook, your email or perhaps your RSS feed.
If you sat down and really thought about what to do next you could probably have figured out at least one step and taken it, but let’s be honest with ourselves—most of the time it is easier to just switch tasks or take a break than it is to plow forward.
Human beings are procrastinators
And that is simply because we are modeled after nature.
Most things in nature take the path of least resistance; electricity, water flowing through pipes, you name it, nature is programmed to take the “easy” route.
Programmers are no different.
Now, I am not saying that we all procrastinate all the time. I’m not making excuses for it either. And, sure, you can overcome your procrastinating habits through focus and self-discipline, but it is not an easy road.
If you are a manager or lead others in this field, it is very important for you to understand this point, because it can help you to break structure work in such a way that the path of least resistance is to get the work done.
If you are an individual developer working on a project, or perhaps your own project, you need to know this as well, because just knowing this will help you to understand how to better structure your day and your time to mitigate the problem of procrastination.
Two are better than one
There are many reasons why pair programming works to increase productivity, but I’ve always held that the most important reason is because it prevents developers from procrastinating.
It is often a tough sell to management that two developers will start working on one computer. Surely sacrificing parallelization has to come at a high cost.
But, when you look at the honest truth of productivity, you find that around 40% or more developers only actually put in about 4 hours worth of real work a day on average.
The world just has too many distractions that equate to the path of least resistance.
Now let me ask you a question. When was the last time you checked your personal email or looked at your stock portfolio when your coworker was sitting at your computer, working on a problem with you?
Suddenly the path of least resistance has changed from seeing what clever thing has been posted on twitter by The Oatmeal to getting the work done.
There are a couple of reasons for this:
- The obvious one. It is impolite to cause your coworker to have twiddle his or her thumbs while you check your personal email.
- Working with someone else greatly decreases the chances of getting stuck.
Remember getting stuck is our big problem. I sincerely believe most developers want to do a good job, not just for their employers, but for themselves as well.
The big problem is when I get stuck, I tend to be like a stream hitting a dam, I just divert and go another direction, (whichever one is easiest.) Now, I manage this weakness of mine in my own way by breaking things up small in order to make those small things become the path of least resistance, but the best thing by far is to have another developer that is smarter than I am sitting next to me or remoted into my machine, who isn’t going to get stuck and helps us plow forward.
Now, I realize this might not apply to you. You might be a super programmer who spends all 8 hours of his or her work day writing perfect code and never getting stuck, and pairing up with a mere mortal just slows you down, but if you are like me you need all the help you can get.
It’s not just pair programming
When I say pairing, I am not just talking about pair programming.
Do you have to have two developers sitting at the same workstation all day long?
No, I do think you should definitely do some of that, but I don’t think it is essential to be constantly pair programming.
What I do think is essential is to have at least two developers working on a single problem at the same time.
It provides some accountability that goes a long way towards making sure work has some progression and it will prevent developers from getting stuck, because they always have someone to bounce ideas off of who is facing the same problem they are and is just as responsible for the delivery of the solution.
If possible it is best to have the whole team involved as much as possible with every backlog, but I realize this is not always possible.
The key thing is that work always progresses, because it is much harder to get stuck if you have two people committed to the same objective. That doesn’t mean that a team can never get stuck, but it is much less likely. Besides, if two or more people are stuck on a problem, it is a good indication that you may be facing a really hard problem or more likely there is something else wrong with your development process that is causing your teams to get stuck.
If one developer is stuck, it might just be because of a weakness in their abilities, but you can almost always count on two or more developers being stuck as a sign of something else.
So, while pair programming is definitely beneficial, it is more essential to have more than one person assigned to a single objective. The real benefit lies in the sharing of fate.
Don’t forget personal time
So, now that I’ve convinced you that pairing up is good and will reduce that procrastination factor, you’re going to rearrange your team and make sure everyone is always working together all day long, right?
Don’t forget that humans are still humans and have lives and priorities that extend beyond their jobs.
It is really important for developers to have time during the day to check their emails, return calls from the school principal, and to just stop for a moment and decompress by reading a news article.
Sometimes the most important revelations come to us when we are taking a break or goofing off.
If you are reading this post as a developer looking to up your productivity, the same applies to you—don’t get carried away.
I’ve seen all kinds of intricate tools to measure how much time you spend doing what throughout the day with stop watch precision, and while there are some benefits to using a tool like this to see how you are spending your time, the pressure of fighting so heavily against your nature is likely to result in a complete abandonment of any kind of time management practice. Time management anarchy!
If you practice pair programming in an environment such as eXtreme Programming, you have to be even more careful to make sure you are scheduling non-pair time to take care of work things like email and self-organization, as well as personal things mentioned above.
I’ve seen many environments where pair programming is supposed to be fun and productive, turn into a sweatshop factory where developers resent not having some space to themselves. (This is one the biggest fears I have found that causes resistance to pair programming in general.)
Pay attention young programmers, this is the most important piece of programming advice you will ever hear.
Well perhaps not, but it might be the most important piece of programming advice you hear today.
“Switching gears is grinding gears.”
I’ve been doing this programming thing for quite a while now, and I have come to realize that the biggest thing that saps my productivity is switching gears.
What do I mean by switching gears?
Many different contexts
Switching gears can apply to a variety of different contexts, but it is basically whenever you are working on some task or technology and have to stop what you are doing and either do something else or change the type of thing you are doing.
This is really a bit different than multi-tasking. Multi-tasking is really trying to do more than one thing at once. It usually involves a large amount of rapid context switches, but for this post I am more concerned about the general idea of breaking rhythm.
I think it is easier to speak about this subject if we talk about some specific applications of the idea and why they are harmful.
In the Agile world of software development today, we often are required to switch from problem domain to problem domain as many of our iterations contain mixes of different features on different parts of the system and bugs to be fixed.
Have you ever been in the situation where you were just beginning to understand how some area of the code base worked, or how to work with a particular customer on a particular problem space and then had to switch to something else and start all over again?
Even when you switch back to the original context you were working with, if enough time goes by, it becomes new again. You have to relearn much of what you had learned the last time and just when you begin to hit your groove, the cycle begins again.
This form of switching gears is at the very least frustrating, and at the most a complete demotivator and productivity sapper.
Unfortunately for most developers, this problem is out of your immediate control. But, take note product owners and project managers, there is a reason why iterations should have a goal.
If you are in the precarious position of being a developer pinned against the ropes, try to make some noise and let your management and product owners know that your team will be much more efficient when you aren’t switching gears all the time.
In my experience, the results of replacing this constant context switching with the synergy of a common goal and related features in a segment of time has an astounding effect on productivity that is hard for any serious businessperson to ignore. So speak up!
Switching technology is painful!
It really isn’t worth trying to fight this because you are going to be going against the technology grain to do so. Although, I do suppose this may be one of the reasons for the recent popularity of Node.js.
I’m not saying to not learn new things. It is very important to always be learning.
What I am saying, is to try to find some kind of rhythm with the technology stack you are working with and try not to switch that up.
Technology specific training can really help here as well. I for one, need to learn JQuery better. The problem is that when I am working on a web based feature, I am not forced to learn JQuery because I am not in that context long enough.
So what do I do instead?
I waste time Googling for answers. I know that I have a short coming here and I need to just bite the bullet and spend some dedicated time to really thoroughly learn JQuery, because by Googling for little pieces of it at a time, I am not really making much headway and the context switch ends up stealing what I do learn from my memory.
One more aspect of this is the idea of focused teams. Many software development groups do not like to specialize their developers onto one focus area. I agree whole-heartily with the idea of non-specialization.
But! There is huge benefit to be gained by keeping the same group of developers working on a specific set of technology or part of the code base for a set period of time. I’ll talk about this a bit more, towards the end of this post, but the basic idea is that it takes time for people to find their groove.
I think it is optimal to break any large team up into smaller technology area focused teams that regularly rotate every 3 months or so. The idea here is that you give those teams enough time to get good at what they are doing and actually commit what they have learned to memory, but you rotate them often enough that they don’t end up becoming specialists which are unable to see the whole picture.
This one typically isn’t an issue, but it can be depending on the environment that you are working in.
Teams need enough time to go through that forming, storming, and norming set of phases. If you are constantly interrupting this process by switching around team members, you are never going to get the team to act as an entity of its own.
Teams are generally more efficient than individuals, because they benefit from synergy, when 1 + 1 = more than 2.
But just like a big truck taking some time to get up speed, a team takes time to get going. Also like a big truck, a team can gain momentum that individual developers seldom can achieve.
A smaller aspect of this is pair programming. I suppose that many have been successful switching up programming pairs once a day or so, but I suppose that more teams have been successful switching up pairs at longer intervals.
For me, this interval varies. Sometimes, I feel like I need to stay paired with a teammate for longer than 2 weeks, which is our regular interval, sometimes 2 weeks is fine. It depends on what you are working on and how much momentum you have.
They key here is to make sure that you are giving teams enough time to take up their own flag and stake their territory. Teams can take some time to find their common goal. Self-direction can really help with this.
Ever tried to turn a flat head screw with a screwdriver, but it doesn’t quite turn, because you can’t seem to get the head of the screwdriver into the groove of the screw?
You twist that screwdriver around a bit until finally it slips into the groove. Then when you turn the screwdriver the screw turns with it.
As humans, we tend to be like screwdrivers, we have to find our groove. We all have this adjustment period where we are fumbling through things.
It is very important to make sure that we aren’t switching gears so often that we are not actually turning any screws once we are in the groove.
Regardless of what kind of context switching you are doing—whether it is problem domain, technology or teams—it is important to make sure that you are not spending 90% of your time finding the groove and only 10% of your time “in the groove.”
Depending on what you are doing and what the context switch is, the proper amount of time before switching contexts is going to vary, but I think it is very important be aware of this phenomenon and plan around it. If you don’t you are going to end up spinning your wheels, which is unfulfilling to say the least.
The topic of code reviews has always caused much debate in many software shops where I have worked.
I am often asked what my opinion of doing code reviews is. My answer might surprise you.
I don’t like them. I prefer not to do them.
Let me be more specific. I don’t like code reviews that happen after the work is already done.
Paired programming = continuous code review?
Yes. That is exactly what I am saying.
Think about it for a second. Can you really have a better, more honest, and more interactive code review than paired programming provides? If two developers are working jointly on a portion of code, it is being reviewed as it is being written.
I’m going to divert a bit to talk about some of the common problems that happen in code reviews, then I’m going to talk about how paired programming solves them.
Code review problems
#1. Not telling the truth
There really is no value in a code review where no one says what they really think is wrong with the code and instead picks out some little non-offensive thing like a naming convention that wasn’t followed.
All too often code reviews are dominated by a fear of insulting the person’s code that is being reviewed. This kind of weak code review provides no benefit. I would go so far as to say it is reinforcing the practice of writing bad code because bad code is rubber stamped.
To have a successful code review everyone has to check their ego at the door. This rarely happens. Code is something that has been creatively designed; not too many people can take a critique of their labor, even fewer of their art.
Without a spirit of humility and openness, code reviews don’t provide any value. It is one thing to point out a problem, it is another thing to do something about it.
#3. Wrong focus
One of the most common errors of code reviews is paying attention to formatting, coding style, or naming conventions. Those topics don’t belong in a code review at all.
Tools can automatically format the code and statically analyze problems with coding style or naming conventions. It is a complete and total waste of time to have a human reviewer review any of those things.
Seriously, if someone comes into a code review and they haven’t run the auto code formatter on their code and they haven’t run the static analysis tools and fixed the problems found there, don’t be rude, just tell them nicely that their code is not ready for review.
Side note here: There is often debate on whether we should enforce code formatting, or enforce coding style, or enforce naming conventions. YES! YES! YES! Consistency is hugely important! Code is read more than written and consistent code is easier to read. Have this discussion once, put together the automated tools to automatically format the code, and automatically check the requirements.
Don’t spend months making up your special coding standards document. Use some rule sets from any number of static analysis tools and start enforcing them. Make them part of your build, make check-ins fail for formatting problems, make your IDE auto-format on save. Deciding the perfect placement of curly brackets and whitespace is not nearly as important as being consistent. Just pick something and enforce it.
Code reviews should focus on design, structure, and understandability of the code. Code reviews should never ever ever ever ever ever ever focus on anything that can be automatically checked or enforced… ever!
#4. Rush & Inconsistency
Teams rarely have or make time for code reviews. If they do, it is inconsistent and not applied to all code, which causes the value to be lost. If you have a huge fence around a perimeter yet a large hole where people can just crawl in, the fence is worthless.
There is no point doing a code review where the code is not reviewed in depth. Just scanning over the code and picking on a few variable names here and there does no good. If you’re not prepared to fully immerse yourself into the code being reviewed, and dive deep down into understanding exactly what it is doing, don’t bother.
Paired programming to the rescue
Paired programming is like just-in-time code reviews. It solves many of these issues by having a common goal and creating a joint ownership in the code.
As you pair up with different members of your team, you are likely to be more honest, be less egotistical, focus on the problem not the conventions, and delve deeply into the code.
It is no secret that my preferred modus operandi is no code review, instead paired programming, with everyone monitoring commits to source control, and can flag something and have a discussion if they see something troubling.
What if paired programming is not an option?
Well, try to make it one. Paired programming is a great investment.
But, if you are not doing paired programming, you absolutely should be doing code reviews. I might have extolled some of the problems with code reviews and I advocate paired programming, but let’s not mince words here.
Pair programming is a better way of doing continuous or just-in-time code reviews. Not doing any form of code reviews is just plain stupid.
If you had a construction team building your house or your 20 million dollar sky scraper and they told you that they were not doing engineering reviews of the work that was done, you would probably fire that construction company on the spot. Building software is several levels of complexity higher than that of most physical construction projects. If you call yourself an engineer and you are not subjecting your work to regular review, you are just an amateur playing “engineer.”
So, if you must do the old-fashioned code review, here are some tips I found useful:
- Encourage people to be honest by doing some exercises where everyone reviews some code that wasn’t written by anyone on your team. Encourage people to be as prejudice as possible when reviewing the code.
- Set your expectations. Code reviews are not an approval process, they are an improvement process. Make sure the team is aware of this. Code reviews are a place you take your code to make it better, and to better your skills. Foster that kind of thinking.
- Automate all of the nit-picky stuff and set coding standards, formatting standards, and style standards. Decide what they will be together, or have your experienced people do it, but get it done, make conformance non-optional, and make it automated.
- Develop consistent standards and practice about doing code reviews. Set aside enough time to delve deeply into the code. Set and enforce standards of when and how code is reviewed.
- Lead by example. Proactively ask members of your team to look at your code and tell you how to improve it. Ask if this can be done a better way. Show a genuine interest in feedback and improvement, this attitude will catch on.
In my last post, I talked about some of the problems of Agile processes and suggested the introduction of a new process which takes some of the best parts of each of the popular processes and condenses them into the Kanban lean-style-thinking of limiting the work in progress.
For this post I want to clearly define what I am calling “Kanbanand” with two primary goals in mind.
- Allow someone who is interested in doing a Kanban like process to find enough information to be successful.
- Create a common thread for people who are already basically doing what I am suggesting.
Three Pronged Fork
I want to present Kanbanand as a three pronged fork. In my mind there are 3 distinct areas of a successful Agile process which must be addressed.
- Business and overall encompassing project process.
- Development practices, including standards and best practices.
- Infrastructure: build systems, deployment, source control.
We must know how to run our day to day process, how we physically construct our product, and how we actually build and deliver the product.
- Project is broken into stories which are small vertical slices through the system which are prioritized.
- A Kanban board is used to make the progress of a team visible and has limits to control the Work In Progress (WIP).
- At least once a day team members meet around the Kanban board in a stand up meeting to talk about the progress of the board.
- The team meets on a regular basis to have a retrospective to discuss how to better improve their process.
- Teams always pull in work, work is never “pushed” in.
- Once work has been approved as “done” it can never be “not done”.
- Find something to measure and measure it.
- The team is responsible for, and empowered to determine how the team accomplishes its goals.
- Roughly same sized stories over irregularly sized stories.
- Stories specifying what, over stories specifying how.
- Stories that are one sentence over stories that are one page.
- Talking about how to move the board forward over talking about what I or someone else did.
- Cross functional teams over specialized teams.
- All code is unit tested.
- Static code analysis tools are used to set code standards, all code must meet those standards.
- Any code that is done, is completely done. It is refactored, it is unit tested, it meets the quality standards.
- Code is never commented out. Anyone is allowed to delete any commented out code at any time.
- Determining code is meeting the quality standards must be done in an automated way.
- No one owns code, anyone can work on any code.
- Documentation is ONLY created when it will serve a known purpose and has an immediate value. (Code should document itself with good names and simple flow, unit tests document the low level requirements of the system. Automated tests document the behavior of the system.)
- Testing requirements come from the customer, not from the developer.
- Test driven development over writing unit tests after the code is done.
- Pair programming over working alone.
- Readable code over smaller sized code.
- Doing things right over doing things fast.
- Showing the customer over asking the customer.
- Impromptu discussions at white-boards over scheduled meetings.
- Building tools that will help make completing ten things faster, than completing one thing faster.
- Writing automated tests over manual testing
- Code is continuously built and integrated as soon as it is checked in.
- Builds build code, run unit tests, run quality checks, produce deployable bits.
- Builds fail if any unit test fails, or any quality check fails.
- Code is only deployed from the exact bits that were produced by the build machine.
- Code can be deployed to any environment with the push of a button.
- Production data never goes to any other environment.
- Developers can always run a local build which is the same as what will be built on the build server.
- Moving forward to fix problems over rolling back.
- Integrating soon over merging later.
- Quick builds over slow builds.
- Deploying on demand over deploying on a schedule.
That is my first crack at it. I have tried to keep the process as simple as possible, but still include as rules the things that I think are most important to be successful. I tried to keep the things that involved judgment calls as values. I believe this provides enough information to allow an organization to create a custom process that will work for them, but will still have enough controls to be consistent in the things that I feel make Agile practices valuable.
Let me know what you think or if you have any suggestions. I will update this post as this list evolves. I am sure there is something I missed or could state in a better way.
Like I said before, if you are doing some form of Kanban, you probably are already doing Kanbanand. If you are doing Scrum, your major change would be to drop the planning and instead try to get same sized stories while limiting your WIP.
Went to Boise Code Camp this weekend and it was great!
There were some really good sessions and good discussions on Agile, Scrum and domain specific languages.
I think events like these are important because they help us to zoom out a little and see what kinds of things other people are doing in our field and what companies around us are interested in high quality software.
Code camps are also a great place to get some experience doing presentations and share what you are working on. Networking opportunities abound.
I presented two talks this weekend. I am posting the links to those here.
The first presentation I did was on Pair Programming.
You can find the presentation on Prezi here.
We also did a live pair programming session, which I thought went pretty well. We ran into some of the issues that often come up with pair programming, like being afraid to tell someone you don’t like their method name.
The second presentation I did was on Creating an Internal DSL for Automated Functional Testing.
You can find the presentation on Slideshare here.
We went over how to go about creating a good automation framework which fills in the gaps between the business language and technical language.
Thanks to everyone who attended.
What is pair programming?
The best example is one I’ll steal from Uncle Bob. If you haven’t read this little dialog before, take a moment to do it now. Pair programming is essentially two developers sharing one keyboard and mouse. Both developers work together to write the unit tests and code to make them pass. Often you will switch who has control of the keyboard and mouse. I intricately tie together this practice with Test Driven Development (TDD), because a large amount of the benefit is in the ability for one developer to say, “Hey let me see the keyboard”, and write a unit test which will make the code fail.
Why pair programming?
There are many benefits some obvious and direct others as a side effect. When you have two developers looking at the same code, you have two sets of eyes looking at the code as it is being written. You have a much bigger coverage area of the problem domain, and are less likely to write bugs or miss something. At the same time you are also having a live code review in the context of the code. Also you are getting two developers familiar with the same piece of code, rather than “the dude who wrote all the DAO code.” These benefits alone make pair programming worth it, but there are a few more. Often one developer would get stuck on a difficult problem where two can easily push through.
Some of the indirect benefits are that when someone works alone they are less likely to be working. Honestly, in an 8 hour programming day you might get 4 hours of work. Now a good amount of this is due to distractions, like email, instant messages, random questions, not just slacking off (although some of it is.) When you have two developers sitting at the same computer, it takes a larger amount of force to cause a distraction. If someone is sitting at my desk, I am less likely to look at my email or be drawn away from the work I am working on. You are more likely to get 6 hours or more out of two developers at the same computer with pair programming.
On the job training and cross training is another large benefit. When you pair up a weak developer with a strong developer you will get the weak developer picking up the good practices of the strong developer. Pair up two strong developers, they teach each other the little tricks that make them so effective and they both become more effective. Pair up two weak developers, and you… get a mess for someone to clean up… Don’t do that! Have a tester who should learn some development, pair them up with a developer or vice versa. Even a product owner or business person can benefit from pair programming to better understand how the application is being developed.
Does it really work?
In my opinion, yes. I have personally seen the benefits over years of doing development work, practicing pair programming whenever possible.