Kent Beck - Extreme Programming. Test Driven Development

Extreme programming(English Extreme Programming, XP) is one of the flexible software development methodologies. The authors of the methodology - Kent Beck, Ward Cunningham, Martin Fowler and others. The name of the methodology comes from the idea of ​​applying useful traditional methods and practices of software development, raising them to a new "extreme" level. So, for example, the practice of performing a code revision, which involves checking the code by one programmer,
written by another programmer, in its "extreme" version is "pair programming", when one programmer is coding, and his partner at the same time continuously looks at the newly written code.
The twelve basic extreme programming techniques (according to the first edition of the book Extreme programming explained) can be grouped into four groups:

  • Fine-scale feedback
    • Test-driven development
    • Planning game
    • The customer is always there (Whole team, Onsite customer)
    • Pair programming
    • Continuous, not batch process
  • Continuous integration
    • Refactoring
    • Small releases
  • Understanding shared by all
    • Simplicity (Simple design)
    • System metaphor
    • Collective code ownership or selected patterns ownership
    • Coding standard or Coding conventions
  • Programmer welfare:
    • 40-hour work week (Sustainable pace, Forty-hour week)

XP involves writing automated tests (program code written specifically to test the logic of other program code). Particular attention is paid to two types of testing:

  • unit testing of modules;
  • functional testing.

A developer cannot be sure of the correctness of the code he has written until absolutely all tests of the modules of the system he is developing have worked. Unit tests (unit tests) allow developers to make sure that each of them individually works correctly. They also help other developers understand why a particular piece of code is needed and how it functions - as you study the test code, the logic of the code under test becomes clear, as you can see how it
should be used. Unit tests also allow the developer to refactor without fear.

Functional tests are designed to test the functioning of logic formed by the interaction of several (often quite impressive) parts. They are less detailed than unit tests, but cover much more - that is, tests that involve a larger amount of code during their execution have a higher chance of detecting any incorrect behavior. For this reason, in industrial programming, writing functional tests
often takes precedence over writing unit tests.
For XP, a more prioritized approach is called TDD (test-driven development). In accordance with this approach, you first write a test that initially does not pass (since the logic that it should check simply does not exist yet), then the logic necessary for the test to pass is implemented. TDD, in a sense, allows you to write code that is more convenient to use - because when writing a test, when there is no logic yet,
the easiest way is to take care of the convenience of the future system.

The main goal of the planning game is to quickly form a rough plan of work and constantly update it as the terms of the problem become clearer. The artifacts of the planning game are a set of paper cards containing customer stories and a rough roadmap for the next one or more smaller versions of the product.

The critical factor that makes this planning style effective is that the customer is responsible for making the business decisions and the development team is responsible for making the technical decisions. If this rule is not followed, the whole process falls apart.

Extreme Programming (XP) is one of the flexible software development methodologies. The authors of the methodology are Kent Beck, Ward Cunningham, Martin Fowler and others.

The planning game

Our world is too volatile and unpredictable to rely on the constancy of the situation. The same happens in software development: about a rare system, we can say that its final appearance was known in advance in detail at the very beginning of development. Usually, the customer's appetite comes with eating: he constantly wants to change something, improve something, and throw something out of the system altogether. This is the volatility of demands that everyone is so afraid of. Fortunately, a person is given the ability to predict possible options and, thus, keep the situation under control.
In extreme programming, planning is an integral part of development and the fact that plans can change is taken into account from the very beginning. The game of planning is that fulcrum, a technique that allows you to predict the situation and painlessly put up with changes. In such a game, you can quickly collect known system requirements, evaluate and plan their development according to priority.
Like any other game, planning has its participants and its purpose. The key player is, of course, the customer. It is he who informs about the need for this or that functionality. Programmers, on the other hand, give a rough estimate of each functionality. The beauty of the planning game lies in the unity of purpose and solidarity between the developer and the customer: if they win, everyone wins, if they lose, everyone loses. But at the same time, each participant goes his own way to victory: the customer chooses the most important tasks in accordance with the budget, and the programmer evaluates the tasks in accordance with his capabilities for their implementation.
Extreme programming assumes that developers are able to decide for themselves how long they will take to complete their tasks and which of them would be more willing to solve one task, and who would be more willing to solve another.
In an ideal situation, a planning game involving a customer and a programmer should be conducted every 3-6 weeks, before the next development iteration begins. This makes it easy to make adjustments based on the successes and failures of the previous iteration.

Release plan

The release plan defines the release dates and user language that will be embodied in each release. Based on this, you can choose the wording for the next iteration. Acceptance tests are produced during an iteration and run within that iteration and all subsequent iterations to ensure that the program operates correctly. The plan can be revised in the event of a significant lag or lead following the results of one of the iterations.
Iterations. Iteration makes the development process dynamic. You don't need to plan your programming tasks long in advance. Instead, it is best to have a planning meeting at the start of each iteration. You shouldn't even try to implement what was not planned. You will still have time to implement these ideas when it comes to them according to the release plan.
By getting used to not adding functionality in advance and using direct planning, you can easily adapt to changing customer requirements.

Iteration planning

Iteration planning begins with a meeting at the beginning of each iteration to come up with a plan of steps to address the programming problem. Each iteration should last between one and three weeks. The statements within the iteration are sorted in the order of their importance to the customer. In addition, tasks are added that could not pass the acceptance tests and require revision. The formulations and test results are translated into software tasks. The tasks are recorded on cards that form a detailed iteration plan. To solve each of the tasks, it takes from one to three days. Tasks that take less than one day can be grouped together, and large tasks can be split into smaller ones. Developers estimate tasks and deadlines to complete them. It is very important for the developer to set the exact time of the task execution. It may be necessary to reevaluate some of the wording and revise the release plan after every three or five iterations - this is perfectly acceptable. If you implement the most important areas of work in the first place, then you will always have time to do the maximum possible for your clients. A development style based on a sequence of iterations improves the development process.

Meeting standing

Every morning a meeting is held to discuss problems, their solutions and to increase the concentration of the team. The meeting is held standing up to avoid lengthy discussions that are not interesting to all team members.
In a typical meeting, most of the participants don’t contribute anything, they just participate to hear what others have to say. A lot of people time is spent to get a small amount of communication. Therefore, the participation of all people in the meetings takes resources away from the project and creates chaos in the planning.
For this kind of communication, a standing meeting is needed. It is much better to have one short, obligatory meeting than many long ones that most developers must attend anyway.
If you have daily standing meetings, then all other meetings should be attended by only those people who are needed and will bring something. Moreover, it is even possible to avoid some meetings. With limited attendees, most meetings can be held spontaneously in front of a monitor, where the exchange of ideas is much more intense.
The daily morning meeting is not another waste of time. It will save you many other meetings and will save you more time than wasted.

Simplicity

Simple designs always take less time than complex designs. So always do the simplest things that can work. It's always faster and cheaper to replace complex code right away before you spend a lot of time working with it. Keep things as simple as possible without adding functionality before it's planned. Keep in mind: Keeping a design simple is hard work.

System of metaphors

The choice of a metaphor system is needed to keep the team within the same framework when naming classes and methods. How you name your objects is very important in understanding the overall system design and code reuse. If the developer is able to correctly predict what an existing object might be named, it saves time. Use a naming system for your objects that anyone can understand without specific knowledge of the system.

Customer on site

The main problem of software development is the lack of knowledge of programmers in the developed subject area. Extreme programming has found a way out of this situation as well. No, this is not an internship for a developer at the customer's enterprise - then he will not want to program. On the contrary, it is the customer's participation in the development process.
How can a programmer, without thoroughly understanding the essence of the issue and not being a telepathic, guess what the customer wants? The answer is obvious. The easiest way to overcome this inconvenience - and extreme programming teaches us to find the simplest solutions - is to ask the customer a direct question. More rigorous approaches require a comprehensive preliminary analysis of the area under development. In certain cases, this is justified, although it is more expensive. Real life experience in running mundane projects shows that it is impossible to collect all the requirements in advance. Moreover, even if we assume that all the requirements have been collected at the moment, there will still be one bottleneck: programs, like everything in nature, are not created instantly, and in the meantime, business processes can change. This should be taken into account.
Many people doubt the possibility of involving the customer in the development process. Indeed, customers are different. If it is not possible to attract a customer or his representative, sometimes it is advisable to temporarily hire a specialist in the area being developed. Such a step will reduce confusion in the work, increase the speed of development and bring the project closer to what the customer wants to get. This can also be beneficial from the financial point of view: after all, the salary of a programmer sometimes significantly exceeds the salary of specialists in other industries.
User Story. User Story (something like a user story) is a description of how the system should work. Each User Story is written on a card and represents a piece of system functionality that makes logical sense from the point of view of the Customer. Form one or two paragraphs of text that is understandable to the user (not very technical).
User Story is written by the Customer. They are similar to system use cases, but not limited to the user interface. For each story, functional tests are written to confirm that the story is correctly implemented - they are also called Acceptance tests.

Testing before development

Testing, in its classic sense, is a rather boring procedure. Typically, a tester is hired who periodically performs the same actions and waits for the day when he is finally transferred to another position or the opportunity to change jobs arises.
In extreme programming, the role of testing is more interesting: now the test comes first, and then the code. How can you test something that doesn't exist yet? The answer is simple and trivial: test your thoughts - what to expect from a future piece of software or functionality. This will allow you to better understand what the programmers need to do and check the functionality of the code as soon as it is written.
But the test may not work either. What, writing a test for a test? And then test for test and so on ad infinitum? Not at all. The test for the test will replace the code. How so? But look: imagine that you need to fix the nut in the middle of the bolt so that it does not turn. What do they do for this? Fasten the second nut close to the first, so that each nut prevents the neighboring nut from turning. So it is in programming: the test tests the code, and the code tests the test.
Experience shows that this approach not only does not slow down, but also speeds up development. After all, knowing what needs to be done and the required amount of work will save time by refusing to sell parts that are not in demand at the moment.

Pair programming

All code for a production system is written in pairs. Two developers sit side by side. One dials, the other looks. They change from time to time. It is not allowed to work alone. If for some reason the second of the pair missed something (got sick, walked away, etc.), he is obliged to review all the changes made by the first.
It sounds unusual, but after a short period of adaptation, most people work great in pairs. They even like it because the work gets done much faster. The principle "One head is good, but two is better." Couples usually find better solutions. In addition, the quality of the code is significantly increased, the number of errors is reduced and the exchange of knowledge between developers is accelerated. While one person focuses on the strategic view of the object, the second implements its properties and methods.

Change of positions

During the next iteration, all workers should be moved to new areas of work. Such movements are necessary to avoid isolation of knowledge and eliminate bottlenecks. Particularly fruitful is the replacement of one of the developers in pair programming.

Collective code ownership

Shared code ownership encourages developers to submit ideas for all parts of the project, not just their modules. Any developer can modify any code to extend functionality and fix bugs.
At first glance, it looks like chaos. However, taking into account that at least any code was created by a couple of developers, that tests allow you to check the correctness of the changes made and that in real life you still have to understand someone else's code in one way or another, it becomes clear that collective ownership of the code greatly simplifies making changes and reduces the risk associated with the high specialization of a particular team member.

Coding convention

You are in a team that has been working on this project for a long time. People come and go. Nobody codes alone and the code belongs to everyone. There will always be times when it will be necessary to understand and correct someone else's code. Developers will remove or change duplicate code, analyze and improve other people's classes, etc. Over time, it will not be possible to say who the author of a particular class is.
Therefore, everyone must obey common coding standards - code formatting, naming of classes, variables, constants, comment style. Thus, we will be sure that by making changes to someone else's code (which is necessary for aggressive and extreme forward movement), we will not turn it into Babylonian Pandemonium.
The above means that all team members must agree on common coding standards. It doesn't matter what. The rule is that everyone obeys them. Those who do not want to comply with them leave the team.

Frequent integration

Developers should integrate and release their code every few hours whenever possible. In any case, changes should never be kept longer than one day. Frequent integration avoids alienation and fragmentation in development where developers cannot communicate in the sense of sharing ideas or reusing code. Everyone should be working with the most recent version.
Each developer pair should release their code as soon as a reasonable opportunity arises. It may be when all UnitTest passes 100%. By submitting changes several times a day, you reduce integration problems to almost zero. Integration is a pay-now-or-pay-later activity. So by integrating changes every day in small chunks, you won't have to spend a week tying the system together just before the project is handed over. Always work on the latest version of the system.

Forty hour workweek

A person, especially if he is a programmer, is capable of many things for the sake of business: staying late at work, going to work on weekends, giving up vacation, staying awake for several days sitting at the keyboard ... In general, what can you not do for the sake of your favorite activity. But extreme programming is categorically against such self-sacrifice and violation of accepted labor law.
This is dictated not only by considerations of legality and humanity, but, first of all, by the need to improve work efficiency and strict organization. After all, extreme programming is a collective game designed not for individuals, but for the entire group as a whole. And such a thing as, for example, pair programming is possible only when the biorhythms of its participants are synchronized. And it is impossible if one person comes to work by nine, and the second by twelve, or one person decides that it is better for him to work on Saturday and Sunday, while the other is uncomfortable.
But the most important thing is that a person needs good rest in order to maintain health and performance. The eight-hour workday and the five-day workweek are set precisely for reasons of maximum productivity. In many Western firms, leaving late from work is regarded as poor progress or inability to properly manage their working time. In most cases, this is the case. And from a medical point of view, delays at work lead to constant fatigue, irritability and decreased brain activity. Is it effective? How to organize constant open communication between developers in such a team, and will pair programming be possible? The answer is negative. The norms are norms, and they should be adhered to.

Conclusion

These techniques are brought together for a reason. Their consistent combination is capable of introducing the development process into intellectual resonance, significantly increasing the quality of the product and bringing the time of its release closer. The main charm of all extreme programming is predictability and minimizing development costs; providing the customer with the product that he wants to receive at the time of release; and, of course, communication and training of developers on the job.

Bibliography:

Extreme programming is a methodology for rapid software development. Consists of a set of techniques and principles that allow, both individually and in a complex, to optimize the development process. This approach also governs the rights of developers and customers.

Rights and roles

In extreme programming, all roles are clearly described. Each role has a distinct set of rights and responsibilities. There are two key roles here: customer and developer.

Customer

A person or group of people interested in creating a specific software product. He has the following rights and obligations:

  • fix the release dates for product versions;
  • make decisions about the planned components of the program;
  • know the estimated cost of each functional component;
  • make important business decisions;
  • know the current state of the system;
  • change system requirements when it really matters.

To successfully exercise their rights, the customer must rely on the data provided by the developers.

Developer

One or a group of two to ten people directly involved in programming and related engineering issues. The developer is endowed with the following rights and obligations:

  • gain sufficient knowledge of the issues to be programmed;
  • be able to clarify details during the development process;
  • provide indicative but candid estimates of labor costs for each functional part or user story;
  • adjust estimates in favor of more accurate ones in the development process;
  • provide an assessment of the risks associated with the use of specific technologies.

Roles within a role

Each of the basic roles of extreme programming can be refined by smaller roles. In XP, it is allowed to combine roles within the same person.

Customer side

Story maker- a specialist in the subject area, who has the ability to clearly state and describe the requirements for the system being developed. This person or group of people is responsible for writing user stories and clearing up misunderstandings from programmers.

Receiver- a person who controls the correct functioning of the system. Has a good command of the subject area. Responsibilities include writing acceptance tests.

Big boss- monitors the work of all links, from developers to end users. He oversees the implementation of the system and related organizational issues. Can also be an investor in a project.

Developer side

Programmer- a person involved in coding and design at a low level. He is competent enough to solve current development problems and provide true estimates of planned tasks.

Instructor- an experienced developer who has a good command of the entire development process and its methods. Responsible for teaching the team aspects of the development process. Implements and controls the correct implementation of the methodologies of the process used. Draws the team's attention to important but for some reason missed development points. At the same time, the instructor, like any other person, is not omniscient and attentive to the ideas of other team members.

Observer is a member of the development team who is trusted by the entire group and monitors the progress of development. It compares the preliminary estimates of labor costs and actually spent, displaying quantitative indicators of the team's work. These are the average speed and the percentage of completed and scheduled tasks. This information is provided to the customer for timely control over the situation. Some of this information is unobtrusively provided to developers, to know the state of the project, the places where difficulties arise and what else can be done.

Diplomat- communicative personality, initiating communication between team members. Since the workflow is minimized, constant communication and transfer of experience within the team is important, as well as a better understanding of the system requirements. The diplomat regulates and simplifies communication between customers and developers. It is an important link in the meetings. He prevents misunderstandings, the height of passions and unnecessary quarrels. A diplomat cannot impose his opinion on the debater.

External roles

Consultant- a specialist with specific technical skills to help developers with difficult tasks. Usually attracted from the outside.

Extreme Programming Rules

Coding convention

You are in a team that has been working on this project for a long time. People come and go. Nobody codes alone and the code belongs to everyone. There will always be times when it will be necessary to understand and correct someone else's code. Developers will remove or change duplicate code, analyze and improve other people's classes, etc. Over time, it will not be possible to say who the author of a particular class is.

Therefore, everyone must obey common coding standards - code formatting, naming of classes, variables, constants, comment style. Thus, we will be sure that by making changes to someone else's code (which is necessary for aggressive and extreme forward movement), we will not turn it into Babylonian Pandemonium.

The above means that all team members must agree on common coding standards. It doesn't matter what. The rule is that everyone obeys them. Those who do not want to comply with them leave the team.

Collective code ownership

Shared code ownership encourages developers to submit ideas for all parts of the project, not just their modules. Any developer can change any code to extend functionality, fix bugs or refactoring.

At first glance, it looks like chaos. However, taking into account that at least any code was created by a couple of developers, that Unit tests allow you to check the correctness of the changes made and that in real life you still have to understand someone else's code in one way or another, it becomes clear that collective ownership of the code greatly simplifies making changes and reduces the risk associated with the high specialization of one or another team member.

CRC Session

Use the Class, Responsibilities, Collaboration (CRC) cards to design the system as a team. Using cards makes it easier to get used to thinking in objects rather than functions and procedures. Also, cards allow more people to participate in the design process (ideally, the whole team), and the more people do the design, the more interesting ideas will be brought in.

Each CRC card is an object instance. Object class can be written on top, responsibilities on the left, interactions on the right. We say "can be written" because when a CRC session is in progress, participants usually need a small number of class name cards and do not have to be completely filled out.

CRC session goes like this: each of the participants reproduces the system saying which messages he sends to which objects. Goes through the entire process message by message. Weaknesses and problems are immediately identified. The design alternatives are also clearly visible in the process simulation.

To put things in order, the limitation of the number of simultaneously interacting two is often used.

Customer

One of the XP requirements is that the customer is always available. He should not just help the development team, but be a member of it. All phases of an XP project require communication with the customer, best of all face to face - on site. Best of all, just assign one or more customers to the development team. Beware, the customer will take a long time, and the customer's office may try to give you an intern as an expert. You need an expert.

User Stories written by the customer with the help of the developers. The customer helps to make sure that most of the desired system functions are covered by the User Story.

When planning a release, the customer needs to discuss the choice of User Stories that will be included in the planned release. It may also be necessary to agree on the period of the release itself. The customer makes decisions related to the goals of the business.

Choose the simplest solution

Simple designs are always easier to implement than complex designs. So always make the simplest solution that can work. If you find something difficult, replace it with something simple. It is always faster and cheaper to replace complex code with simple code before you start understanding complex code.

Refactor someone else's code if it seems complicated to you. If something looks complicated, this is a sure sign of a problem in your code.

Keep the solutions as simple as possible for as long as possible. Never add functionality for the future - before the need arises. However, keep in mind: keeping the design simple is hard work.

Functional tests

Acceptance tests (previously also called Functional tests) are written based on User Story. They view the system as a black box. The customer is responsible for checking the correctness of the functional tests. These tests are used to verify the health of the system before it is released into production. Functional tests are automated so that you can run them frequently. The result is communicated to the team and the team is responsible for scheduling functional test fixes.

Frequent integration

Developers should integrate and release their code every few hours whenever possible. In any case, changes should never be kept longer than one day. Frequent integration avoids alienation and fragmentation in development where developers cannot communicate in the sense of sharing ideas or reusing code. Everyone should be working with the most recent version.

Each pair of developers should release their code as soon as there is a reasonable opportunity to do so. This can be when all UnitTests pass 100%. By submitting changes several times a day, you reduce integration problems to almost zero. Integration is a pay-now-or-pay-later activity. Therefore, by integrating changes daily in small portions, you will not have to spend a week to tie the system into one whole immediately before the delivery of the project. Always work on the latest version of the system.

For the manager. If a developer does not submit changes for more than one day, this is a clear indicator of a serious problem. You must immediately figure out what the matter is. All the experience of XP teams says that the reason for the delay is always bad design and it always has to be redone afterwards.

Planning an Iteration

An Iteration Planning Meeting is called before the start of each iteration to schedule the tasks to be done in that iteration. For iteration, User Stories are selected that the customer selected in release plan starting with the most important for the customer and the worst (associated with risk) for the developers. Non-working Functional Tests are also included in the iteration.

User Stories and Failed Functional Tests are broken down into tasks. Tasks are recorded on cards. These cards are the detailed plan for the iteration. Each task should be between 1 and 3 ideal days in length.

Developers disassemble tasks and estimate the length of time it takes to complete them. Thus, each developer estimates how long the task will take from him. It is important that the developer himself makes the final estimate of the scope of work.

Project speed determines whether your tasks fit into iteration or not. The total duration of tasks scheduled for an iteration should not exceed the speed achieved in the previous iteration. If you have typed too many, then the customer must decide which User Stories to postpone to the next iteration. If you typed too little, then you need to add the following User Story. In some cases, you can ask the customer to split one of the User Stories into two in order to include the part in the current iteration.

Delaying a User Story for the next iteration can look scary, but don't allow yourself to sacrifice refactoring and Unit Tests to get more done. Debt in these categories will quickly slow your speed. Don't do what you think is needed in the next iterations - do only what is necessary to complete the current User Stories.

Keep track of project speed and pending User Stories. It is possible that the release plan will have to be redone every three to five iterations. This is fine. After all, the release plan is a look into the future and it is natural to expect that your predictions will have to be adjusted.

Iteration

Iterative development increases the flexibility of the process. Divide your plan into iterations of 2 to 3 weeks duration. Maintain a constant iteration duration for the duration of the project. Let iteration be the pulse of your project. This is the rhythm that will make measuring progress and planning simple and reliable.

Don't schedule tasks in advance. Collect instead Planning an Iteration at the beginning of each iteration to plan what will be done. It is also considered a violation of the rules to run ahead and do what is not planned in this iteration. Thus, it becomes possible to keep under control the changing requirements of the customer.

Take iteration completion deadlines seriously. Measure progress as you work. If you can see that you cannot complete all the scheduled tasks by the deadline, then collect the Iteration Planning again and reevaluate the tasks and postpone some of the tasks.

Concentrate your efforts on completing the most important tasks selected by the Customer, instead of having a few unfinished tasks selected by the developer.

Change tasks

It is necessary to periodically change tasks for developers to reduce the risk of concentration of knowledge and bottlenecks in the code. If only one person on your team can work in a given area and that person leaves, or you just have a lot to do in this segment of the program, you will find that your project is barely moving forward.

Cross Training is usually an important aspect in companies that try to avoid concentrating knowledge on one person. Moving people around the code in combination with pair programming discreetly makes Cross Training for you. Instead of one person who knows everything about a given piece of code, everyone on your team knows a lot about the code in each module.

The team becomes much more flexible if everyone knows enough about each part of the system to start working on it. Instead of waiting for the "guru" to finish working on a critical piece of code, multiple programmers can work on it at the same time.

When starting a new iterations every developer has to move on to a new task. Pairing helps overcome the adaptation problem (which means that a new developer can pair up with an experienced developer in the field).

This practice also stimulates new ideas and code improvements.

Save optimization for later

Never optimize anything before you finish encoding. Never try to guess where the performance bottlenecks will be. Measure!

Make it work, then make it right, then make it fast.

Pair programming

All code for a production system (which means excluding trial solutions) is written in pairs. Two developers sit side by side. One dials, the other looks. They change from time to time. It is not allowed to work alone. If for some reason the second of the pair missed something (got sick, walked away, etc.), he is obliged to review all the changes made by the first.

Sounds unusual, but XP claims that after a short period of adaptation, most people work fine in pairs. They even like it because the work gets done much faster. The principle "One head is good, but two is better" applies. Couples usually find better solutions. In addition, the quality of the code is significantly increased, the number of errors is reduced and the exchange of knowledge between developers is accelerated.

Ruthlessly Refactor!

We programmers tend to stick to a design long after it gets awkward. We keep reusing the unwieldy code because it still somehow works and we are afraid to mess it up. But is it really beneficial? XP takes the view that it is not profitable. When we remove redundancy, improve outdated design, remove unused chunks - we refactor. Refactoring ultimately saves time and improves product quality.

Ruthlessly revise any code to keep the design simple as you develop. Keep your code clear and understandable so that it is easy to understand, modify, and extend. Make sure everything is written once and only once. Ultimately, it takes less time than tweaking a convoluted system.

Release Plan

The Release Plan is developed at the Release Planning Meeting. Release Plans describe a view of the entire project and are used later to plan iterations.

It is important that technical people make technical decisions and business people make business decisions. Release Planning defines a set of rules that allow everyone to make their own decisions. These rules define the method for developing a work plan that satisfies all.

The essence of the release planning meeting for the development team is to evaluate each User Story in ideal weeks. An ideal week is how long you think it will take to complete a task if nothing distracts you anymore. No dependencies, no additional tasks, but including tests. The customer then decides which tasks are most important or have a higher priority.

User Stories are recorded on cards. The Developers and the Customer shuffle the cards together on the table until they get a set of User Stories, which together will make up the first (or next) Release. Everyone wants to release a useful system that can be tested as soon as possible.

A release can be scheduled by time or by volume. In order to determine how many User Stories can be implemented by a specific date or how long a given set of tasks will take in real time, the speed of the project is used. If you plan on time, multiply the number of iterations by the speed of the project to find out how many User Stories can be implemented. When planning by volume, divide the total number of ideal weeks required for all User Stories by the speed of the project and you will get the number of iterations required to complete the release.

If management is not satisfied with the deadline for completion, it may be tempting to reduce the scope estimates. You should never do this. Underestimated ratings are bound to create a lot of problems later on. Instead, negotiate with managers, developers, and customers until you have an acceptable release plan for everyone.

Frequent Releases

Developers should release versions of the system to users (or beta testers) as often as possible.

Release Planning is used to find small functional fragments that have significant business sense and which can be released into the real environment in the early stages of development. This is critical to getting useful feedback in a timely manner so that you can influence the development process. The more you delay the release of an important part of the system, the less time you will have to fix it.

Trial solution

Create trial solutions to answer complex technical questions, to justify certain technological solutions. There is a risk in any technology decision and trial decisions are designed to mitigate it.

Make a program that reproduces the problem under investigation and ignores everything else. Most of the trial solutions are not intended for future use, so expect them to be thrown away. The purpose of their creation is to reduce the risk of making the wrong technical decision or to more accurately estimate the time to implement a User Story.

Meeting standing

Every morning a meeting is held to discuss problems, their solutions and to increase the concentration of the team. The meeting is held standing up to avoid lengthy discussions that are not interesting to all team members.

In a typical meeting, most of the participants don’t contribute anything, they just participate to hear what others have to say. A lot of people time is spent to get a small amount of communication. Therefore, the participation of all people in the meetings takes resources away from the project and creates chaos in the planning.

For this kind of communication, a standing meeting is needed. It is much better to have one short, obligatory meeting than many long ones that most developers must attend anyway.

If you have daily standing meetings, then all other meetings should be attended by only those people who are needed and will bring something. Moreover, it is even possible to avoid some meetings. With limited attendees, most meetings can be held spontaneously in front of a monitor, where the exchange of ideas is much more intense.

The daily morning meeting is not another waste of time. It will save you many other meetings and will save you more time than wasted.

Metaphor of the System

Always choose System Metaphor - a simple and straightforward concept for team members to call all things the same name. For understanding the system and avoiding duplicate code, it is extremely important how you name the objects. If you can guess what is the name of any object in the system (if you know what it does) and it really is called that - you will save a lot of time and effort. Create a naming system for your objects so that everyone on the team can use it without special knowledge of the system.

Unit Tests

Unit tests play a key role in XP. They allow you to quickly change the code without fear of making new mistakes. Unit test is written for each class, the test should check all aspects of the class's work - test everything that may not work.

The trick here is that the test for the class must be written before the class itself. This means that as soon as you release the first working result, it will be supported by the testing system. To conduct tests, a special testing system is written with its own interface.

Unit test for a class is stored in a shared repository along with the class code. No code can be released without a Unit test. Before submitting the code, the developer must make sure that all tests pass without errors. Nobody can give the code if everyone hasn't passed 100%. In other words, since all the tests passed before your changes, if you have errors, then this is the result of your changes. You and fix. Sometimes the test code is incorrect or incomplete. In this case, you need to correct it.

It is a huge temptation to save money on Unit tests when time is short. But by this you are only deceiving yourself. The more difficult it is to write a test, the more time it will save later. This has been proven by practice.

Unit tests allow for collective ownership of the code. They make it relatively easy to revise bad code. Also Unit tests allow you to have a stable working system at any time.

User Story

User Story (something like a user story) is a description of how the system should work. Each User Story is written on a card and represents a piece of system functionality that makes logical sense from the point of view of the Customer. Form - one or two paragraphs of text that is understandable to the user (not very technical).

User Story is written by the Customer. They are similar to system use cases, but not limited to the user interface. For each story, functional tests are written to confirm that the story is correctly implemented - they are also called Acceptance tests.

Each User Story is given a priority by the business (user, customer, marketing) and an estimate of the lead time by the developers. Each story is broken down into tasks and a time is assigned to it when it will begin to be implemented.

User Stories are used in XP instead of traditional requirements. The main difference between User Story and requirements is the level of detail. The User Story contains the minimum information necessary to make a reasonable estimate of how long it will take to implement it.

A typical User Story takes 1-3 weeks of ideal time. A story requiring less than 1 week is too detailed. A story requiring more than 3 weeks can be split into parts - separate stories.

Project speed

Project Speed ​​(or simply speed) is a measure of how quickly work gets done in your project.

To measure the speed of a project, you simply have to calculate the size of User Stories, or how many (in time) tasks were completed in an iteration. Just calculate the total time to estimate the volume of work (ideal time).

During release planning, project speed is used to estimate how many User Stories can be produced.

During iteration scheduling, the project speed in the previous iteration is used to determine how many User Stories to plan in the current iteration.

This simple mechanism allows developers to recover from a difficult iteration. If you have free time after recovery, go to the customer and ask for more User Story. As a result, the speed will increase again.

Do not use this parameter as absolute. It is not suitable for comparing the productivity of two projects, since each team has its own characteristics. This parameter is only important for the team to keep it on an "even keel".

You should expect small changes in project speed as you work. But if the speed changes a lot, you need to reschedule the release. As soon as the new system goes to users, expect the speed of the project to change as you have support tasks.

When an error is found

If an error is found, a test is created to prevent it from reoccurring. An error that occurs on a production system (already installed) requires writing a functional test. Creating a functional test just before diagnosing a bug allows customers to clearly describe the problem and communicate the problem to the developers.

Failed functional test requires creating Unit Test... This helps focus debugging efforts and clearly shows when the bug has been fixed.

You don't need it

Refrain from filling the system with things that you will need in the future. Only 10% of what you expect will actually be needed in its original form, that is, 90% of your time will be wasted.

There is always a temptation to add functionality now and not later, because we see how to add it now and feel that the system will be much better. But we must always remind ourselves that we will never need it. Additional functionality only slows down progress and eats up resources. Forget future requirements and added flexibility. Concentrate on what needs to be done now.

Probably, every designer or analyst at least once in his life came across a customer who wants to get his project as cheaply as possible and, in addition, in the shortest possible time. But if the cost of the project is a very real subject of bargaining, then it is much more difficult to negotiate the adjustment of the project delivery date. There are more and more impatient customers today, which is explained by the state of the modern dynamic market, and the falling level of trust between performers and customers, and the behavior of investors whose appetite comes with eating (if there is a more or less working version of the product, money for further development give much more willingly), etc. In this regard, the classical development methodologies (in which a long cycle of actual design and information collection, when the client invests heavily, but does not receive a real result for a long time) enter into a very tough contradiction with the interests of an impatient customer. All this gave impetus to the development of alternative design methodologies in two main directions: increasing customer confidence by providing real evidence of a successfully developing development process and a sharp reduction in product development time. A group of such methodologies is called "active programming".

Accelerated and collaborative application development

Typically, end users and management representatives of the client company assume that the design process has failed if real off-the-shelf components are not available. Often, the customer insists on the early implementation of the project implementation stage in order to get a specific result and demonstrate it as soon as possible. In this case, there is a great temptation to choose accelerated application development (ERD) or collaborative application development (CAP). Such methods involve developing a working prototype and then demonstrating it to users who note what they like and what they don't. After that, the designer finalizes the prototype, taking into account the comments made, and then again demonstrates what happened. The process repeats until users are satisfied with what they see and the prototype becomes a working application. Usually, a time limit and number of iterations are set, otherwise users will endlessly demand new improvements to the prototype. In theory, this allows you to get exactly the system that users need.

So here we see an iterative development model with very short spiral cycles in both cases. Both methods reduce the time spent on the initial stages of design: strategy (either omitted altogether or merged with analysis), analysis (in most cases, it is limited to primary sampling of information and analysis of forms - as a rule, reports, according to which they try restore the structure of the system functions), design (aimed at obtaining the primary prototype as quickly as possible). The result of the development is a prototype, which is then subject to industrial implementation. In this case, testing is carried out with the active participation of the customer, or the customer becomes a tester (at best, a beta tester).

In practice, this approach to application development is fraught with the problems listed below:

All attention is focused on screen forms, and everything related to data processing rules and system functions remains behind the scenes. There is a temptation to start working with reports, while a report is not a start-up, but a derivative product of an information system.

Users assume that if the prototype variant is agreed, then the module is ready. In fact, it can be just a picture with a set of "stubs" for calls to system functions and interaction with other modules.

Modules are designed in isolation from each other. The consequence of this is the contradictions of modules, duplication of functions and data, which can only be revealed when testing a complex of modules.

Functionality is built in parallel in several directions, so the structure of the data warehouse must be controlled. With RBM, the database schema resembles a dump, where tables are wasted and the result is a set of conflicting and duplicate data.

Documentation when using the ERM method is usually absent for two reasons: there is not enough time and the illusion is created that the user is able to understand the essence of what is happening without documents. Problems arise when the application does not behave as expected by the user.

Exception handling methods are different for different modules.

The problem of integration of modules arises: as a rule, an integral system does not work out, because it was originally designed as a set of components, which were subsequently hastily interconnected.

Product quality control comes into sharp conflict with the terms of project development, as a result of which the stages of testing and implementation of the next version of the product are practically merged and transferred directly to the customer's landfill. It is clear what happens in this case to the customer, who is extremely dissatisfied with the quality of the product; in other words, dirty linen in public is taken out absolutely at the wrong time.

The question arises: is it possible to solve such problems and how? After all, I really want to get the project as quickly as possible! To some extent, extreme programming (eXtreme Programming, XP) can be considered an evolution, and possibly a revolution in the field of younger active programming methodologies. Whether this methodology is suitable specifically for your development team is up to you and only you, since, for example, not everyone is delighted with extreme sports.

Extreme programming

XP Principles and Methods Used to Accelerate Development

The father-ideologist of extreme programming is considered Kent Beck (Kent Beck). XP is a fairly young methodology, the assessments of which are very controversial - from enthusiastic to sharply negative. The main principles are:

Simplicity of solutions.

Intensive development in small groups (no more than 10 people), active communication in a group and between groups (communication).

Feedback from the client (feedback), who is actually involved in the development process.

Sufficient courage and willingness to take risks.

The first factor in accelerating development is iteration: development is carried out in short iterations with an active relationship with the customer. XP is an iterative development process that is not revolutionary in and of itself. It is proposed to make the iterations as such short, the recommended duration is 2-3 weeks and no more than 1 month. During one iteration, a group of programmers must implement several properties of the system, each of which is described in a user story. User stories in this case are the initial information on the basis of which the module is created. User stories differ from use cases: the user story is short - 1-2 paragraphs, while use cases are usually written in sufficient detail, with main and alternate streams - thus, approximately a page plus a diagram is obtained (the most common formalization is currently proposed in UML); User stories are written by the users themselves (who are part of the team in XP) as opposed to the use cases that a systems analyst usually writes. They strive to compensate for the lack of formalization of the description of the input data of the project in XP by actively including the customer in the development process as a full-fledged member of the team and by having constant contact with the customer (active communication and continuous feedback support). In this case, extreme is the degree to which the customer is attracted to the programming kitchen, which is due to the desire to shorten the development timeline through communication and feedback.

The second factor in accelerating product development is the presence of small teams and pair programming (when two programmers create code together in one common workplace). All this is aimed at achieving a high level of communication in the group, as well as at the earliest possible detection of problems (both errors and missed deadlines). Pair programming pursues the goal of stabilizing the project, since with this methodology there is a high risk of code loss due to the departure of the programmer, who could not stand the intensive work schedule. In this case, the second programmer from the pair plays the role of the "heir" of the code (which in classical methods is implemented in the technical documentation). It is also important how the groups are distributed in the workspace - in XP, an open workspace is used, which assumes quick and free access for everyone to everyone; Typically, the workspace is built around a circle.

The third factor in accelerating process development is making the first simplest working decision. In this case, the extreme nature of the method is associated with a high degree of decision risk due to the superficiality of the analysis and a tight time schedule. The minimum set of main functions of the system is implemented at the first and each subsequent iteration; functionality expands with each iteration.

Practices

Usually XP is characterized by a set of 12 actions (practices) that must be performed in order to achieve a good result. XP practices do not define the XP process itself, but XP does define those practices — that is, following the practices does not guarantee results. None of the practices are fundamentally new, but XP brings them together.

Planning game The whole team gets together, a collective decision is made about what properties of the system will be implemented in the next iteration. The set of properties is determined by user stories. The XP-labor intensity of each property is determined by the programmers themselves.

Close interaction with the customer (feed-back, on-site customer). The customer must be a member of the XP team (on-site customer). He writes user stories, selects stories to be implemented in a specific iteration, and answers business questions. The customer must be an expert in the subject area being automated. Constant feedback from the customer (feed-back) is required.

System metaphor. A good metaphor for system means simplicity in naming classes and variables. In real life, finding a metaphor is extremely difficult; finding a good metaphor is not easy. In any case, the team must have uniform naming rules.

Simple architecture Any property of the system should be implemented as simply as possible. Programmers in the XP-team work under the motto: "Nothing superfluous!" The first simplest working solution is accepted, the required level of functionality is implemented at the moment. This saves the programmer's time.

Coding conventions. Coding standards are needed to support other practices: collective code ownership, pair programming, and refactoring. It is at least more difficult to carry out these practices without a single standard, but in reality it is impossible at all: the group will work in a mode of constant lack of time. No detailed standards are required, only important things need to be standardized. The definition of the most important objects of standardization in XP is subjective.

Refactoring Refactoring is the optimization of existing code towards simplification, which involves constant work to simplify the code. By keeping the code transparent and defining its elements just once, programmers can reduce the number of bugs that need to be fixed later. When implementing each new property of the system, the programmer must think about whether it is possible to simplify the existing code and how this will help to implement the new property. In addition, refactoring should not be combined with design: if new code is created, refactoring should be postponed.

Pair programming is one of the most famous XP practices. All programmers should work in pairs: one writes the code, the other looks. Thus, it is necessary to place a group of programmers in one place, which is easiest to do at the customer's site (all the necessary team members are geographically located in one place); XP works most successfully in unallocated teams of programmers and users.

40-hour work week. The programmer should not work more than 8 hours a day. The need for overtime is a clear indicator of the problem in this particular area of ​​development; in addition, the customer does not pay for overtime work in XP. Finding the causes of overtime and eliminating them as soon as possible is one of the basic rules.

Collective code ownership Every programmer in the XP team should have access to the code of any part of the system and make changes to any code. Mandatory rule: if a programmer made changes and the system after that does not work correctly, then it is this programmer who must correct the errors. Otherwise, the work of the system will be like total chaos.

Frequent change of versions (small releases). The minimum iteration is one day, the maximum is a month; the more often releases are made, the more system flaws will be identified. The first releases help to identify shortcomings at the earliest stages, then the functionality of the system is expanded (based on the same user stories). Since the user is involved in the development process from the first release, he evaluates the system and issues a user story plus feedback. Based on this, the next iteration is determined: what will be the new release. In XP, everything is geared towards providing continuous user feedback.

Continuous integration. The integration of new parts of the system should occur as often as possible, at least once every few hours. The basic rule of integration is the following: integration can be performed if all tests pass successfully. If the tests fail, then the programmer must either make corrections and then integrate the components of the system, or not integrate them at all. This rule is strict and unambiguous - if there is at least one error in the created part of the system, then the integration cannot be performed. Frequent integration allows you to get a ready-made system faster, instead of spending a week on assembly.

Testing Unlike most other methodologies, testing in XP is one of the most important things. An extreme approach is that tests are written before the code is written. Each module must have a unit test - a test of the given module; thus, in XP, regression testing is carried out (reverse testing, "non-degradation of quality" when adding functionality). Most errors are corrected at the coding stage. The tests are written by the programmers themselves; any programmer has the right to write a test for any module. Another important principle: the test defines the code, and not vice versa (this approach is called test-driven development), that is, a piece of code is put into the repository if and only if all tests are successful, otherwise this code change is rejected.

So XP is extremely dismissive of all development artifacts other than source code. The XP process is highly informal, but requires a high level of self-discipline. If this rule is not met, then XP instantly turns into a chaotic and uncontrollable process. XP does not require programmers to write a lot of reports and build a lot of models. In XP, every programmer is considered a skilled worker who takes his duties professionally and with great responsibility. If this is not the case in the team, then it is absolutely pointless to implement XP - it is better to start with rebuilding the team. The development risk is reduced only in a team for whom XP is ideal, in all other cases XP is a development process with the highest degree of risk, since there are simply no other methods of reducing commercial risks, except for the banal human factor, in XP.

Existing risks of applying the methodology

It is worth highlighting the risks of XP that can fail a project if they are not taken into account and not prevented.

Planning game. Programmers implement only those functions that are necessary for the capabilities selected by the customer at a given iteration. As a result of such a decision, the development of the system remains behind the scenes, as a result of which, during development, it becomes necessary to build "stubs" and rewrite the code.

Continuous customer involvement (on-site customer). During the period of work on the system, the customer's representative is in the development team, and the requirements for the qualifications of this person or team are very high. If the client does not agree to provide expert level personnel, then the project falls into the highest risk group.

Metaphor. The general view of the system is defined using a metaphor or a set of metaphors, on which the customer and programmers work together. If the process is not logged and the naming structure is not standardized, then the process can be endlessly iterative.

Simple architecture At each moment of time, the system being developed performs all tests and supports all the relationships defined by the programmer, does not have duplicate code and contains the minimum possible number of classes and methods. This rule can be briefly expressed as follows: "Formulate each thought once and only once." This principle conflicts with the speed of writing code. Without high self-discipline and rigid code standards, the system immediately falls into a risk group.

Frequent change of versions (small releases). The system is put into operation within a few months after the start of implementation, without waiting for the final resolution of all the problems posed. The frequency of new releases can vary from daily to monthly. It is impossible to test a more or less complex component in such a period; the customer actually acts as a beta tester. Systems requiring continuous reliable operation (the so-called 24-7 requirement) are at risk.

Refactoring system. The system architecture is constantly evolving. The current project is being transformed, while ensuring that all tests run correctly. Extreme programming assumes that it is always possible to remake part of the system, and at no special cost. However, practice quite often testifies to the opposite.

Continuous integration. The new code is integrated into the existing system within a few hours. After that, the system is reassembled into a single whole and all tests are run. If at least one of them is not executed correctly, the changes made are discarded. In this case, it is not always clear who exactly will fix errors, and not only local ones, but also those induced by the wrong code. Complex tests are not expected at this stage; in addition, changes are saved even if an error is detected.

Pair programming. All project code is written by teams of two using one workstation. The human factor in this case plays a decisive role: whether the couple works or not, there is no third way.

40-hour week (40-hour weeks). Overtime work cannot exceed one working week in duration. Even occasional overtime work that is repeated too often is a sign of serious problems that need to be addressed urgently. As the practice of using extreme programming shows (despite a number of positive examples cited by the supporters of this method), overtime with this approach is the rule, not the exception, and the struggle with problems in this case is a constant phenomenon. It intensifies during the period of replacing the current raw version of the product with the next one - less raw. If the customer does not receive ongoing evidence of system improvement, then you are in serious trouble.

Collective ownership Each programmer has the opportunity, if necessary, at any time to improve any part of the code in the system. Without a source code control standard, the development process becomes completely uncontrollable.

Open workspace. The development team is housed in a large room surrounded by smaller rooms. In the center of the workspace, computers are installed on which pairs of programmers work (and in accordance with the above principles, all this should be located at the customer's site, since he is very actively involved in the development process). If there is a geographically distributed group of developers and customers, the project requires standardization of the interaction protocol (quickly, reliably, reliably) or falls into a risk group.

Tests Programmers write unit tests all the time. Taken together, these tests should work correctly. For iteration stages, customers write functional tests that are also required to work properly. However, in practice this is not always achievable. To make the right decision, you need to understand what it will cost to return a system with a known defect, and compare this with the cost of the delay in fixing it. Tests written by the programmers themselves (especially when working overtime) are not fully functional, and even more so they do not take into account the peculiarities of multi-user work. Developers usually don't have enough time for more advanced tests. This problem is solved by attracting contactors for a certain period, which is associated with the large role of the human factor: since there is initially no technical documentation, information is transmitted through the communication of programmers. Although, of course, you can build a development system in such a way that the same people will do everything from start to finish. To what has been said, it must be added that testing the system is not at all limited to tests of components (units); tests of interaction between them are no less important, the same applies to tests of operational reliability. Nevertheless, the method of extreme programming does not provide for the creation of tests of this class. This is due to the fact that such tests themselves can represent a rather complex code (this is especially true for tests that simulate the real work of the system). This technology also does not take into account yet another important class of tests - tests of the system's behavior with an increase in the amount of processed information. With a high frequency of version changes, it is technologically impossible to perform such a test, since its implementation requires a stable and unchanged project code, for example, within a week. In this case, you will have to either pause the development of components, or create a parallel version of the project for the duration of the test, which will remain unchanged, while the other will change. Then you will need to go through the code merging process. But in this case, the test will have to be created anew, since the methods of extreme programming simply do not provide for the development of tools that allow predicting the behavior of the system under certain changes. To solve these problems in XP is proposed through the same human factor and self-discipline.

Nothing more than just rules. The members of the team working on the technology of extreme programming undertake to abide by the stated rules. However, these are nothing more than rules, and the team can change them at any time if its members reach an agreement in principle on the changes made. This principle is heavily dependent on the human factor; violation of the discipline of development entails missed deadlines and, as a result, leads to the collapse of the project.

As a result, we get a method that is potentially highly adaptable to seriously and frequently changing requirements for a project, but at the same time it is not free from a number of fundamental shortcomings and is highly dependent on the human factor.

Thus, the result of applying the method of extreme programming can turn out to be either extremely good or extremely bad.

Extreme Programming - or XP (eXtreme Programming) for short - is the programming community's response to the onslaught of formal approaches to software development and is designed to bring creativity back to the developer community.

Any idea brought to the point of absurdity degenerates into its own opposite. This is precisely the situation in the North American RAD software industry. At some point, tools designed for rapid application development began to supplant everything else in the minds of managers, including developers, customers and the project itself. Unjustified, exaggerated attention to the Process to the detriment of other development factors gave rise to a lot of formal procedures - but the quality of the products received and the number of successful projects turned out to be disappointing.

To resist the pressure of formalism in the work of programmers is called upon the initiative of a group of developers, united under the slogan of Extreme Programming, or XP.

At the core of extreme programming are several very specific, often quantified principles that define what, when, and how to do it. While not perceiving these numbers as dogma, one must nevertheless bear in mind that they appeared as a result of the analysis of numerous successful and unsuccessful projects, so that at least there should be good reasons for making your own amendments.

Extreme programming is not based on specific techniques, as is commonly believed, but only four basic principles: communication, simplicity, feedback and courage. It is with them that you need to start.

Extreme programming offers a ready-made solution: keep everything as simple as possible, keep the customer with you or stay with the customer yourself, let him actively follow the development process, welcome the changes - and success is almost guaranteed.

In XP teams, communication is always welcome - the fastest means of sharing information and experience. This is very important when maximum development speed is required. But communication, like any other useful endeavor, requires constant support. That is why someone from the team must take responsibility for monitoring communication, becoming a so-called diplomat. Communication and the need to explain your actions to other team members forces you to do everything as simply as possible. If it doesn't work the first time, they work on simplification over and over until the main goal is achieved - the maximum comprehensibility of the code to other developers.

Extreme cycle

Extreme programming is based on a very short, repetitive development cycle of one to three weeks. By the end of each cycle, there should be a fully working, functional, and tested release of the application. These cycles should be repetitive and uninterrupted throughout the project.

A prerequisite for such a mode of operation is the proven fact that requirements are rarely complete, timely and correct. In other words, no matter how well the application is planned, it will have to be redesigned 100%. Moreover, it may have to be redone even at the final stage. You should not postpone rework until the end of the work, you need to do them regularly.

As a consequence of constantly changing requirements, another principle follows - late decision making.