Category Archives: Process

Eating Frogs: A Short Case for Incremental, Risk-Driven Software Development

“Eat a live frog first thing in the morning, and nothing worse will happen to you for the rest of the day.”

-Mark Twain

If you have ever been a software project manager, business analyst, developer, or purchaser of software development services, how many times have you encountered a project with the following characteristics:

  • All the requirements are done up front, with an emphasis on getting them “perfect.”
  • Design follows the same path as requirements – all designs and mockups must be complete before development proceeds.
  • In the project plan, coding for the system is broken out into “iterations” – one piece of the code is built at a time.
  • Project managers and technical leads schedule developers to implement the easy, simple requirements first in order to show rapid progress and build momentum.
  • When clients are shown the product at the end of iterations, they ask for changes that ultimately send shockwaves through the rest of the requirements.

At this point, most large projects are destined either to go significantly over schedule or over budget, or they fail outright – the project is scrapped. The reason for this is two-fold.

  1. The Waterfall lifecycle is masquerading as an iterative and incremental lifecycle.
  2. Management is pushing key risks to the end of the project.

 The Rational Unified Process (RUP) is a generally-accepted solution to this problem. It provides a framework within which iterative and incremental software development can occur in a way that reduces risk over the lifecycle of a project. RUP is based on several principles:

  • Use-case Driven Development:  Use cases guide the development of the system from requirements all the way through test. They also provide system use context far superior to list-based requirements.
  • Risk Driven Development:  The most complex, significant, and risk-laden parts of the system are developed first. Over the lifetime of the project, risk decreases since the “harder” parts are done first.
  • Architecture Driven Development: Related to risk driven development, the early iterations of development focus on the parts of the system most critical to its structure, providing a framework around which the rest of the system can be developed with relative ease
  • Iterative and Incremental: The system is developed one small piece at a time with frequent end-user input. This ensures that the right system is being developed, and that there are no surprises at UAT time

Though RUP is a proven process, it can cause some indigestion for those unfamiliar with it – and especially those most familiar with the waterfall model. Some points of pain for RUP are:

  • Requirements are not complete before development begins
  • Initial progress can seem slow due to the addressing of high risk items early in the project; it takes longer to establish momentum
  • The process wreaks havoc on traditional project schedules – long range estimates for the completion of the project are best given towards the end of the Elaboration phase… after some development is already completed

 On the whole, however, RUP presents far fewer risks that traditional waterfall development. Waterfall projects often veer wildly off schedule due to surprises near the end of the build phase – this is far more risky than RUPs practice of postponing long-range scheduling to the end of Elaboration. Waterfall projects may show lots of early progress as developers pick of low hanging fruit – but the benefits are fleeting; sooner or later the big risks are going to be encountered and, if they’re show-stoppers – all that low-hanging fruit was picked for nothing. Finally, requirements rarely, if ever, remain stable throughout waterfall development. While RUP may seem disquieting in addressing requirements in chunks throughout the process, this is really no different than what happens in waterfall – with the exception that RUP plans for the changes and is structurally built to handle them.

If you’re interested in trying this process, highly suggested reading is The Unified Software Development Process by Jacobson, Booch, and Rumbaugh. It’s dry reading, but full of wonderful and detailed information about how the process works.

The Joy of Continuous Integration – Episode 1

This is the first of a multi-part series on continuous integration, featuring Hudson CI, by Counterpointe Solutions’ Michael Kim.

I recall a quick conversation I had with a friend and former colleague, Paul Duvall, who wrote a book about continuous integration (CI) a couple of years ago. I was not well versed in CI at the time, but these days I’ve been testing out a number of tools to incorporate the concept into our projects at Counterpointe. The open source CI tools available these days enable relatively easy and cost effective implementations. I have been researching two common tools – Hudson CI and Cruise Control – to compare the two to see which would work better in different situations. This is an account of the lessons I’ve learned.

No man is an island

Both Hudson CI and Cruise Control don’t do much on their own. To use the tools for greatest effect, you’ll need to have to understanding and experience with version control software like CVS or Subversion, and management/administration of applications servers(e.g. JBoss or Glassfish) and integration testing frameworks (e.g. JUnit, TestNG, Selenium). It’s a daunting list of things to know, but having that foundational knowledge will help you understand all the configurable items that Hudson provides.

When is CI appropriate?

If you’re working on a one-person project, a CI process is likely overkill. You should only attempt putting one together if you’re interested in learning the concept or putting together a pilot for a larger project. However when you go to projects with two or more developers working on the same set of code, or you have teams working on components with dependencies on one another, CI begins to show its benefits. When someone checks in compile-defective or run-defective code, it can have a negative cascading effect on productivity. The project may not be able to move forward until the author of the buggy component corrects the issue.

The three big issues CI can address

The first issue CI can handle is compilation issues. These can be resolved quickly by a CI process, which will checkout the latest code from version control, run a build, and notify the team of any issues.

The second issue is that of runtime issues at the unit-level. After compiling code from version control, CI processes can execute unit tests and report problems automatically.

Last, but certainly not least, CI can address integration testing by loading data via SQL scripts and executing test scripts against a database and application server that the application is running on – a vital tool for conducting regression tests.

Putting the pieces together

Beyond setting up Hudson CI itself, you will need to have version control set up so that Hudson can draw code from it. You will also require supplimental open source tools to integrate Hudson with your version control, such as Ant and build scripts to automate the compilation, build, and deployment processes. Finally, you will need both data-loading SQL scripts and a tool to control your application server. More details on these issues will be provided in later installments of this series.

That’s all for now. My next entry will step through setting up the environment to integrate Hudson with version control.

About the author
Michael Kim is a Principal Developer at Counterpointe Solutions, whose primary focus is on Java EE development process and system architecture.

Follow

Get every new post delivered to your Inbox.