Values, Principles and Practices of XP
Outstanding software development through Extreme Programming.
I'm currently reading Extreme Programming Explained: Embrace Change and wanted to write about the values, principles and practices of XP.
Personally, I think XP is extremely interesting because it is about social change. I already wrote an article about what it is: What is Extreme Programming?.
I find it cool that a team that may be struggling, that isn't doing well, still, with the very same members, by applying the philosophy of XP, can actually accomplish greater things than imagined!
Values are why we do something.
Principles are domain-specific guidelines for life. They are the bridge between values and practices.
Practices are the things we do day-to-day.
Values are important. Sometimes we are too focused on the individual actions and don't understand how they create value, or if any at all. They are important in order to have a clear purpose or direction as to why we are doing certain practices, and not just doing or following things blindly.
XP embraces five values to guide development: communication, simplicity, feedback, courage, and respect.
Communication matters most in a software development team. Sometimes problems arise because of the lack of communication, which could've been prevented. Communication is important for creating a sense of team and effective cooperation.
Simplicity is about solving today's problem in the most simple fashion. It only makes sense in context, in some scenarios, the most simple solution will require more work than the more complex ones. What was simple yesterday may look complex today. To regain simplicity, you must find a way from where you are to where you want to be.
No planned paths remain valid for long. In software development, change is unavoidable, but change creates the need for feedback. In XP, feedback is used to get closer to the goals. Don't strive for instant perfection, rather improvements.
Generate as much feedback as your team can handle as quickly as possible. The key is our quick response to feedback.
Shorten the feedback cycle. The sooner you know, the sooner you can adapt.
Feedback is a crucial part of communication. It tells us what we should or can improve.
Courage is effective action in the face of fear.
It is about how we handle our fears that determine whether we are working as an effective part of the team.
The courage to speak truths, pleasant or unpleasant, fosters communication and trust. The courage to discard failing solutions and seek new ones encourages simplicity. The courage to seek real, concrete answers creates feedback.
Respect is extremely important. If members on a team don't care about each other, care about the project, the values of XP and the importance of it, then XP won't simply work.
Every person whose life is touched by software development has equal value as a human being. No one is intrinsically worth more than anyone else. For software development to simultaneously improve in humanity and productivity, the contributions of each person on the team need to be respected. I am important and so are you.
Values are too abstract to directly guide behavior, XP though, introduces principles that are meant to guide software development.
Human beings are the ones developing software. It is a fact.
Acting like software isn’t written by people exacts a high cost on participants, their humanity ground away by an inhumane process that doesn’t acknowledge their needs.
The book mentions 5 points that are needed for developers to become good:
Basic safety: Freedom from hunger, physical harm, and threats to loved ones. Fear of job loss threatens this need.
Accomplishment: The opportunity and ability to contribute to their society.
Belonging: The ability to identify with a group from which they receive validation and accountability and contribute to its shared goals.
Growth: The opportunity to expand their skills and perspective.
Intimacy: The ability to understand and be understood deeply by others.
The magic of great teams is that after the team members develop trust they find that they are free to be more themselves as a result of their work together.
After all, work is still work. Private details of life confuse team communication and can even damage the culture. Whether it is you sharing too much of your private life, personal matters, or asking others things that are private and not work-related. Separate work and life-related stuff that is private and has zero effect on your work.
Software costs. Someone or multiple people paid or invested in it.
Make sure what you are doing has business value, meets business goals, and serves business needs. For example, solving the highest priority business need first maximizes the value of the project.
The earlier software makes money, the sooner the development is valuable.
Mutual benefit in XP is about activities benefitting all concerned. This principle is about finding practices that benefit me now, me later, and the customers as well.
Practices guided by this principle are easier to sell due to the immediate and future relief of pain they come with.
For example, someone struggling with a difficult bug is ready to learn TDD. Since it benefits them now, and will in the future, as well as their teammates.
Huge internal documentation of software violates this principle, because such documentation may be helpful to someone in the future, but definitely does not benefit me at the current moment, though, at the current moment it would slow me down tremendously.
The book brings up 3 points how XP mutually deals with communication-with-the-future problems:
I write automated tests that help me design and implement better today. I leave these tests for future programmers to use as well. This practice benefits me now and maintainers down the road.
I carefully refactor to remove accidental complexity, giving me both satisfaction and fewer defects and making the code easier to understand for those who encounter it later.
I choose names from a coherent and explicit set of metaphors which speeds my development and makes the code clearer to new programmers.
This principle is about copying the structure of one solution into a new context.
For example, the basic structure of development is that you write a failing test and then make it work. This structure operates at all different scales.
Take into account, this principle is a good start, but it may not always work.
Do your best today but strive to do better tomorrow, strive to have a deeper understanding tomorrow.
XP shines in this aspect, it is about always improving.
Perfect in this case is a verb, we strive to perfect our development, teamwork, processes, design, stories, etc.
Put improvement to work by not waiting for perfection. Find a starting place, get started, and improve from there.
Teams need to bring in people from different backgrounds, with different attitudes, experiences, expertise, etc. In order for the team to have multiple different ways of thinking and solving a problem, instead of people being alike and having similar backgrounds and experiences.
Discussions will surely arise, which solution to pick to a certain problem.
The principle of diversity suggests that the programmers should work together on the problem and both opinions should be valued.
It is about resolving the conflict productively, value all the opinions, and strive together to find a way to develop the most valuable software in the time available.
Good teams reflect after action, regularly.
They think about why and how they are working.
Why did we succeed? What should we continue doing?
Why did we fail? What can we do better or differently?
Reflect and strive to improve. Even if everything seems perfect, know that there is always room for improvement and throw in the question:
- Why do things seem perfect? What are we doing well? What can we do better in order to succeed even more?
Flow in software development is delivering a steady flow of valuable software by engaging in all the activities of development simultaneously.
Don't deliver software in big portions.
This principle suggests that for improvement, you deploy smaller increments of value ever more frequently.
Learn to see problems as opportunities, opportunities for learning and improvement.
In some instances it can be very difficult to know what to do about a problem, then what you may really need is time, patience to solve a problem.
Part of being extreme is consciously choosing to transform each problem into an opportunity: an opportunity for personal growth, deepening relationships, and improved software.
The crucial, difficult problems in software development should be solved in multiple ways. If one solution fails, at least the others will prevent a disaster from occurring.
The cost of the redundancy is more than paid for by the savings from not having the disaster.
Sometimes it is extremely difficult to implement something, we don't know which way or approach to take, try the ideas you have, even if they fail!
Failure isn't a waste, rather a learning experience.
Be aware of falling into the trap of discussing or thinking forever and not getting things done.
When you don’t know what to do though, risking failure can be the shortest, surest road to success.
Projects don't go faster by lowering the quality, rather that often (if not always) results in later and less predictable delivery, especially due to the amount of time spent on fixing bugs for example.
Pushing quality higher often results in faster delivery.
A concern for quality is no excuse for inaction. If you don’t know a clean way to do a job that has to be done, do it the best way you can. If you know a clean way but it would take too long, do the job as well as you have time for now. Resolve to finish doing it the clean way later.
Take baby steps. Making big changes in big steps is dangerous.
People and teams can take many small steps so they appear to be moving forward rapidly.
Baby steps acknowledge that the overhead of small steps is much less than when a team wastefully recoils from aborted big changes.
Responsibility cannot be assigned; it can only be accepted. If someone tries to give you responsibility, only you can decide if you are responsible or if you aren’t.
The practices of XP are divided into two parts, the primary ones and the corollary ones. With the primary ones, you can start right away and get the immediate improvement, which each one of them. The corollary practices will probably be very tough if you haven't mastered the primary ones first.
Master the primary practices before moving to the corollary ones.
Develop in an open space big enough for the whole team. Meet the need for privacy and “owned” space by having small private spaces nearby or by limiting work hours so team members can get their privacy needs met elsewhere.
The authors tell a story where they learned two lessons. The problem is always a people problem, technical fixes alone aren't enough. The second lesson was the importance of sitting together and communicating with all our senses.
Include on the team people with all the skills and perspectives necessary for the project to succeed.
A sense of wholeness should exist on the team. All the necessary resources to succeed should be available.
We are in this together.
We support each others’ work, growth, and learning.
What forms a whole team is dynamic. If a set of skills becomes important, bring a person in with the right expertise. If someone is no longer needed, he can go elsewhere.
Make your workspace about your work.
Despite making the workspace about work, it should also provide for other human needs. In order to provide comfort and encourage social interactions, put water and snacks in place. Make sure to keep the place clean and structured, which leave helps the mind thinking about the problems.
From my personal experience, a clean environment is crucial for feeling good mentally, for mental health, at least for me.
People also need privacy, perhaps provide small spaces, separate cubes, or limit the work hours.
Work as many hours as you can productively. Take care of yourself. Burning yourself out due to putting in more work isn't good for you nor your team.
Software development is a game of insight, and insight comes to the prepared, rested, relaxed mind.
When you are sick, respect yourself and your team by resting and getting well. Your health comes first.
In my opinion, even if you feel like crap because of a bad night's sleep or due to an incident that has happened, take a day off and recharge, heal.
Coming in sick doesn’t show commitment to work, because when you do you aren’t helping the team.
Work the same amount of hours, just manage it better. Perhaps have a 90-minute session a few times throughout the day of focused work/coding, try finding what works for you.
Pair programming is a dialog between two people simultaneously programming (and analyzing and designing and testing) and trying to program better.
Keep each other on task.
Brainstorm refinements to the system.
Take initiative when their partner is stuck, thus lowering frustration.
Hold each other accountable to the team’s practices.
Though, if you need privacy and time to work on an idea, go ahead and do it. We need both companionship and privacy.
Make sure to rotate pairs frequently and take frequent breaks, pairing can be tiring, but surely is rewarding.
Plan using units of customer-visible functionality.
When a story is written, try as early as possible to estimate the development time to implement it.
Estimation gives the business and technical perspectives a chance to interact, which creates value early, when an idea has the most potential. When the team knows the cost of features it can split, combine, or extend scope based on what it knows about the features’ value.
Give the stories a short title and a description. Write them on cards and put them on a wall that is often being passed.
In XP stories are estimated extremely early, which gets the team thinking about how to get the largest return from the tiny investment.
Plan work a week at a time at the beginning of every week. In that meeting:
Review progress to date, including how actual progress for the previous week matched expected progress.
Have the customers pick a week’s worth of stories to implement this week.
Break the stories into tasks. Team members sign up for tasks and estimate them.
Start off by writing automated tests that will run when the stories are completed. Then complete the stories and get the tests to pass. The goal is to have software in a deployable condition at the end of the week.
The nice thing with a week is that everyone is focused on Fridays.
Every quarter plan the next themes. Also reflect on the team, the project and its progress.
During this quarterly meeting:
Identify bottlenecks, especially those controlled outside the team.
Plan the theme or themes for the quarter.
Pick a quarter’s worth of stories to address those themes.
Focus on the big picture, where the project fits within the organization.
Themes fit well into larger-scale planning and aren't as detailed as stories.
This seasonal planning also fits well with other business activities that happen quarterly.
Always include minor tasks that be dropped in every plan, in case you get behind. It is important in an atmosphere of distrust and broken promises to meet your commitments, by meeting a few commitments, in the long run, relationships can be rebuilt.
Be aware of falling into the trap of overcommitting and underdelivering.
Clear, honest communication relieves tension and improves credibility.
There are many ways to structure slack.
It can be that you have to start with yourself, estimating honestly to yourself the time it takes to implement a certain task and communicating honestly and openly with the rest of the organization, even if they aren't ready for it.
Automatically build the whole system and run all of the tests in ten minutes. A build that takes longer than ten minutes will be used much less often, missing the opportunity for feedback.
Manual builds are worse than automated ones, they tend to be done less often and less well, which in turn results in more stress and errors.
Integrate and test changes after no more than a couple of hours.
The longer you wait to integrate, the more it costs and the more unpredictable the cost becomes.
The common style is the asynchronous one. Shortly after checking in the changes, the build system starts to build and test. In case something goes wrong, you get notified via email, text message or some other way.
Integrate and build the complete product. Continuous integration should be comprehensive enough that the next deployment is not a huge deal.
Write a failing automated test before changing any code.
The book mentions 4 problem Test-First Programming addresses at once:
Scope creep: It’s easy to get carried away programming and put in code “just in case.” By stating explicitly and objectively what the program is supposed to do, you give yourself a focus for your coding. If you really want to put that other code in, write another test after you’ve made this one work.
Coupling and cohesion: If it’s hard to write a test, it’s a signal that you have a design problem, not a testing problem. Loosely coupled, highly cohesive code is easy to test.
Trust: It’s hard to trust the author of code that doesn’t work. By writing clean code that works and demonstrating your intentions with automated tests, you give your teammates a reason to trust you.
Rhythm: It’s easy to get lost for hours when you are coding. When programming test-first, it’s clearer what to do next: either write another test or make the broken test work. Soon this develops into a natural and efficient rhythm—test, code, refactor, test, code, refactor.
Invest in the design of the system every day.
Strive to make the design of the system fit greatly for the needs of the day.
XP teams work hard to create conditions under which the cost of changing the software doesn’t rise catastrophically. The automated tests, the continual practice of improving the design, and the explicit social process all contribute to keep the cost of changes low.
Because of this, XP teams are confident in their ability to adapt the design to future requirements.
Invest in the design in proportion to the needs of the system so far.
As for where to improve the design, the book mentions having found the elimination of duplication very helpful.
Designs without duplication tend to be easy to change. You don’t find yourself in the situation where you have to change the code in several places to add one feature.
Incremental design states that it is most efficient to invest in design close when it is being used.
As mentioned above, starting with these practices before having the primary ones applied, is very difficult and the book even describes it as dangerous. For example, daily deployment is pointless if your team continuously ships code filled with bugs.
Real Customer Involvement
Get feedback directly from the customers weekly and quarterly. The goal is to avoid wasted effort by making sure we are on the right path, and always adding value.
When replacing existing systems, take one step at a time. Big deployments hardly ever work and are a high-risk bet. Instead, replace a piece of functionality and deploy the system. You can also find a way to run both systems in parallel. This will likely result in the users having to learn using both versions, but is worth the price to pay in order to make sure the project succeeds.
Effective teams, teams that trust each other and have solid relationships, should work together. Good software is not just developed due to what people know, but also their relationships and trust between one and the other. Ignoring these values can lead to fewer or worse things being accomplished than before. Also, make sure to rotate a fair amount in order to spread the knowledge and experience across the company.
Great teams will get better as time pass, and do more in less time. Gradually reduce the team size once the work process has been improved and the team has eliminated wasted effort, and make sure to keep the workload constant.
Every time the team makes a mistake, a bug or defect occurs, learn from it and why it happened, and also think of steps to take in order to prevent this from ever happening again.
The book mentions 4 points to take when responding to a defect:
Write an automated system-level test that demonstrates the defect, including the desired behavior. This can be done by the customer, by customer support, or by developers.
Write a unit test with the smallest possible scope that also reproduces the defect.
Fix the system so the unit test works. This should cause the system test to pass also. If not, return to 2.
Once the defect is resolved, figure out why the defect was created and wasn’t caught. Initiate the necessary changes to prevent this kind of defect in the future.
For the fourth step, you can use an exercise from Taiichi Ohno, the Five Whys, in order to find the heart of the problem and make sure to forever prevent it from happening again.
Anyone on the team should be able to improve any part of the system. This can be attempted after the team has developed a deep sense of responsibility and takes pride in their work.
Code and Tests
The only permanent and accurate descriptions of the system are the code and tests. They are the most important type of documentation because they are always up to date, and should be treated with such importance.
Customers pay for the what the system does today and what the team can make the system do tomorrow.
Single Code Base
The team should strive to work on a single codebase. Temporary branches are fine but shouldn't be worked on for too long, according to the book not more than a few hours. Different versions of code often result in more conflicts, bugs and duplicated work.
The gap between development and production code should be kept small by putting new software into production every night. The bigger the gap is, the higher the risk of failure when you deploy. Small and frequent deployments allow you to make good decisions due to accurate feedback.
If you are far away from deploying daily, start by striving to deploy more often. Sometimes it can be tough because something is blocking the process towards deploying more frequently, work on removing these barriers and let frequent deployment slowly but surely take place.
Negotiated Scope Contract
Usually, time and cost are fixed in software development. By adding quality to the equation, you can negotiate on scope. Don't drop quality, otherwise, the project will start to deteriorate.
Avoid long contracts and instead release in smaller chunks by having short contracts.
The idea is, as you get feedback from customers, you want to be able to respond to change and integrate new features if necessary, but instead, due to long contracts, you will be forced to work on old requirements.
If you still find a problem not covered by one of these practices, go back to the principles and values, and come up with a solution that is fitting for your team's needs.