A variety of practices, principles, values, and other factors go into making a project agile. In this section, we describe the more important ones (we also sum up these practices as a “top 10” list at the end of this chapter).
A doomed project is one that fails to adapt its development process as it goes along. If a particular practice obviously isn’t working, it should be
Keeping a process
is the art of producing just enough documentation to proceed, and having just enough process hoops to jump through to provide some structure and coordination, without
ICONIX Process aims to keep the project low ceremony, by identifying a minimum set of UML diagrams that can be produced to get reliably from use cases to code with as few hoops to jump through as possible.
If sufficient time is spent on getting the architecture and design right near the start of the project, then it becomes a lot easier to extend and modify the design later on (when changes are traditionally more expensive).
As we describe later in this chapter, Robert C. Martin identifies the need for
—that is, constant attention to the design and the state of the source code. If the design begins to fray at the edges (e.g., because some functionality is being added that the design wasn’t originally intended to cope with), then time needs to be spent readjusting the design and tidying up the code through refactoring. The alternative—just shoehorning the new functionality in (also known as hacking)—means that the problem never goes away, and over time it just gets
Instead, designing for change (also known as defensive programming ) means following sound, object-oriented (OO) design principles, the following in particular:
Keep the code in a highly modular state
. Make sure each class has just one responsibility, and that it handles that responsibility well. Also, make sure each method
Keep your classes highly cohesive and loosely
Don’t overcomment your code
. Any code that you have control over should be made self-explanatory (see the
Use class names that are closer to the problem domain than the implementation details . We’ll explore this in more detail when we talk about domain models in Chapter 3.
Don’t overcommit . That is, don’t use a concrete type where a more abstract type would suffice. For example, if you’ve declared a return type as a java.util.ArrayList , you might find it’s better to declare the return type as a Collection interface instead. And speaking of interfaces …
Use interfaces as return types and parameter types wherever possible .
One of the most important factors separating agile development methods from traditional development methods is the focus on people. For example, Agile Modeling promotes communication and teamwork through the following practices:
Active stakeholder participation
Modeling with others
You build systems for your stakeholders. It is their requirements that you need to fulfill, they are the source of critical information, and they need to make important decisions such as the setting of priorities. For iterative and incremental development to succeed, your stakeholders must be available to provide information, to work with you to explore their requirements, and to make decisions in a
Software development is a lot like swimming: it is very dangerous to do it alone. Whenever you work on something by yourself, you risk going in an inappropriate direction and not
Agile processes do place a greater emphasis on the people factor, but it’s debatable whether this is intrinsically what makes a project agile. Respecting your co-workers is equally important on nonagile projects, for example. If people feel valued, they’ll be more productive, and more willing to participate and contribute actively to the project.
We can also reduce the likelihood of requirements changing at the most inopportune moment by getting from use cases to code in as short a time frame as possible. We do this by spending a little extra time focusing on the requirements and the design modeling (when a change in the requirements is welcomed), so that we cut a straight line to the source code, developing short iterations in short spaces of time.
If working software has been delivered to the customer, then we know we’ve made at least some progress (even delivering a small amount of working functionality to the customer is a lot further than some projects get). Working software can also be used to measure (in precise terms) how near to completion the project is (see Chapter 9 for more on agile planning).
But how do we know that the software is working? “Working” doesn’t just mean “doesn’t crash”; it means that the software matches up with the customer’s requirements—that is, it does what it’s
During analysis and design, you should constantly ask yourself, “How am I going to test this?” If you can’t test something, then you should seriously consider whether you should be building it. Considering testability while modeling is important because it keeps the team focused on realistic designs. Furthermore, it gives the team a head start on writing the test cases, as some thought has already been put into them. Model reviews, described in Chapter 3, are also a good option for validating both the requirements and the design.
As with improving communication and teamwork, the people factor plays a large part in agile project management. In many ways, this is no different from the “traditional” project management role: it’s about managing groups of people and keeping them at their optimum efficiency without burning them out.
In practical terms, this might simply involve seating people near appropriate colleagues so that they’re more inclined to communicate well, moving individuals across
Agile planning operates at two levels:
: This involves planning ahead, tracking changes, and adapting the plan as the project progresses.
, on the other hand, involves making
: This entails preparing for the unknown so that when changes take place, their impact is kept to a minimum. Agile planning is a way of
Typically, agile planning consists of various practices, including performing short, fixed-length iterations (usually of 1 to 2 weeks); regularly reviewing the project plan; time boxing (i.e., specifying a fixed amount of time in which to deliver a variable amount of functionality); and tracking velocity (i.e., the rate at which new working software is being delivered).
While some agile methodologies tell us to “embrace change,” we prefer to see change as something that should be actively managed—controlled, even. This doesn’t mean discouraging change (that wouldn’t be very agile, after all), but instead keeping a pragmatic focus on the costs involved in making a change to the requirements at a late stage in the project.
If the customer is made aware that change isn’t free, and that the cost to fix a requirements defect
This goal is probably the most intrinsically
of the agile factors listed here. The customer might, in all good faith, specify a set of requirements at the start of the project, believing them to be correct. During the project, however, things change. The business changes,
Agility is all about recognizing that these things happen in just about every software project and, rather than trying to suppress them (e.g., by “freezing” requirements with another 8 months to go before the deadline), we use change to our advantage to drive the project toward the working system that is the most optimal for the
We can use a variety of practices to achieve this goal. In fact, pretty much all of the agile practices contribute to this goal in some way.
[5.] See Martin Fowler’s paper “The New Methodology” at www.thoughtworks.com/us/library/newMethodology.pdf.
Use Case Driven Object Modeling with UML : A Practical Approach (Addison-Wesley Object Technology Series)
User Stories Applied: For Agile Software Development
ICONIX Process Roadmaps: Step-by-step Guidance for SOA, Embedded, and Algorithm-intensive Systems
Design Driven Testing: Test Smarter, Not Harder