When Kent Beck joined the C3 project at the Chrysler corporation in 1996 to do performance tuning on their payroll system, he felt the need to refine the development methodology adopted in the team. To do that, he took the best practices used in the development industry for the last 35 years, and tried to unite them and take them to the ’extreme level’. That’s how the Extreme programming (or XP) software development methodology was born.
Twenty years later XP is adopted in a lot of development companies and keeps evolving and proving itself as a reliable methodology for creating successful products. Nowadays XP is one of the most solid-standing approaches in software communities, although some of its practices have been significantly reviewed, updated or redefined as corollary.
Extreme programming paradigm is aimed to help people make higher-quality software in a more productive way, and that’s why we at RubyGarage are following that paradigm as well. And to understand how do we do it, it’s important to start with explaining the four basic XP activities.
- Coding. Code is the main part of the product. Everything can be implemented through the code only, so writing effective code becomes a priority #1. One of the XP principles explains that the product changes should be incremental: you’d better make small releases once per three weeks rather than one big release in a year.
- Testing. The more tests you do, the more flaws you can eliminate. To adopt this approach, XP offers to write and run:
- unit tests to confirm the validity of every piece of written code before proceeding to implementing the next feature
- acceptance tests to check if the code satisfies the customer’s product requirements
- integration tests to detect troubles related to the interaction of software modules
To turn all those activities into an effective workflow usable for product development, multiple practices were developed. In this post we’d like to share the practices we use in our everyday routine. Here they are:
To write the code in the most effective way, we follow the pair programming practice, when one person writes the code and thinks about the smallest details, while the other one focuses on the overall picture and reviews the code.
The developers usually switch their roles within an hour, and such pairs are not predefined — people are pairing in different ways for each new task. That allows to guarantee that all developer team members are familiar with the code, know the current progress, can learn from others and be involved in planning meetings.
While it's primarily helpful for writing a better, defect-free code, pair programming has additional advantages: it helps to build a strong team, make developers more satisfied of their work and consider a bigger variety of solutions before solving a problem.
Around 20% of all code-related tasks at RubyGarage are done through pair programming; others are usually too quick, too typical or too simple to involve two developers. The pair programming practice is often used for more complicated goals, when a few decisions should be considered and discussed to find the best one.
In general, the planning game practice is a practice of making meetings before each sprint to plan the near-term releases and current tasks for the developers. A few ways are offered to do that; we stick to the planning poker variation, explained in another Agile methodology called Scrum.
The basic idea behind planning poker is to simultaneously unveil everyone’s thoughts and expectations on how complex is a task and thus how much efforts it requires to be done. That allows ’players’ to avoid becoming biased after the more experienced developer has revealed his own thoughts, which would otherwise happen in case of turn-based poker.
The complexity of a task is measured by story points. One story point is an arbitrary measure defined and negotiated previously by the team; it represents estimated efforts required to make some typical or familiar task within the current project. The idea behind story points is that different developers may solve the same problem in the same way, but it may take different time for them to do that depending on their competency and experience. Thus, measuring required efforts is more effective than measuring time in planning poker.
So here’s what the whole process looks like:
A product manager explains the task to be estimated and answers the related questions. Then every developer makes an estimate and takes the corresponding card showing a total number of story points the task requires in order to be done; nobody can see what cards were taken. (A special deck was designed for that matter, however, usual notes can be used or a smartphone with an app for that). Then everyone shows the cards taken at the same time.
The ones who had the highest and lowest estimates then explain their decisions. Often, if the discussion starts taking too much time, the project manager (or a moderator, if there is any), can use the timer to cease the negotiation.
After that the developers make new estimates considering the new arguments and info, take new cards and everything starts again until the consensus is found.
A study in 2007 made by Haugen and his colleagues had shown that this approach is pretty effective: after making a few experiments with planning poker practice it was found that the final estimation perfectly corresponded to the real time the task required to be done.
Test driven development
As written before, to provide the best quality for a product and guarantee its reliability and durability, it should be tested a lot. The test driven development approach offers to follow an extreme strategy when writing a new piece of code: the developer should write as many tests as possible until he can no longer think of ways to break the written code.
To write effective tests a developer follows the next short instruction:
- Set up the environment, i.e.,provide code with necessary data before testing it.
- Execute the code (run the test).
- Verify the results. Note: the code should not simply work, but behave as expected.
- Clean up the environment to be sure next tests are not affected by previous ones.
The algorithm for the whole TDD approach is simple. To write a new piece of code, the developer makes the next cycle over and over again, often referred as to ‘Red -> Green -> Refactor’:
- Red: Defines the behavior he wants to implement next and then writes a test (also with as few lines of code as possible), which should fail unless the required behavior is present.
- Green: Writes enough code just to make the required functionality work and pass the previously written test. Fixes that code if needed until the test is passed.
- Refactor: Improves the code to make it readable and having no duplication and code smells without changing its current behaviour. After each small change the previously written test should be run to avoid errors.
Refactoring here plays a role that can be hardly underestimated. Without this practice, your product may appear unstable, have code smells and technical debt resulting in potential problems with further development and improvement of the software. Refactoring, if done according to the XP methodology, allows to avoid any potential problems related to scalability, reliability and security of the product in future.
The product team should deploy the new version of the software frequently in order to be ready for sudden changes (and thus new requirements). In RubyGarage we have sprints (1, 2 or 3 week long), and the new version is released at the end of each sprint. All members are always working with the latest version of the product to avoid integration problems.
Since software is updated frequently, and the implemented changes usually correspond to the current requirements, sometimes there might be troubles with adding new features to the existing product architecture. To avoid that, code refactoring should be done every now and then to make that architecture simpler and thus more flexible, extensible and scalable for new changes. In Ruby Garage we go further and have refactoring as a part of the test driven approach to avoid the need for refactoring in the future. Thus, the code gets refactored even before it is merged with the code on the production server.
To make the code clear and readable for everybody, extreme programming methodology offers to have a set of rules accepted within a team explaining the coding standards. We in RubyGarage stick to the community-driven code style guides written for most tools that we use, like Ruby, Ruby on Rails, PHP, Symfony 2 and CoffeeScript.
Another practice related to shared understanding of the product is collective code ownership, when all the team members can review and edit any part of the product code, which makes all the team responsible for the final result. In GitHub it is achieved by the requirement for all team members to review each opened pull request and approve it.
Not only this is a great team-building practice, but also an effective way to speed up the development process, since any error can be fixed by any developer in the team.
If the task seems to be somehow complex, it means you can simplify it and break into smaller tasks. The smaller the task, the easier it is to write the corresponding code and test it. As extreme programming methodology puts it, «Simple is best».
Finally, if we’re speaking about making the team work more productively, it’s important to provide developers with enough time to rest. Thus, they should not work more than 40 hours per week. If that happens, the next week such person should work less hours to balance such overtime.
All that practices, when implemented, help to keep the sustainable pace and move on in a very dynamic and productive manner. Frequent code-merge, refactoring and collaborative way of working require developers to be always alert and stick to the project’s schedule.
For the RubyGarage team the extreme programming practices have proved its effectiveness long ago. In fact, some of these practices were adopted in most of the companies, so don’t be surprised if you find out that others take advantage of, say, pair programming or test driven development — it’s indeed the finest ways to create working and reliable software!