Teaching A Goliath to Fly Why Goliath Why Fly Salim Nair Prasad Ramnath Agile Development Conference 2005 Denver, Colorado
The good stuff first This is a story of applying agile practices in a large legacy code base. Here are the lessons we learnt Refactoring legacy code cannot work in isolation Legacy code is not bad code; just legacy code Refactor just enough to put your feature under test. Follow simple architectural principles Agile development in a legacy framework can only work by evolution. Start refactoring bottom-up, followed by a periodic top-down review to unify the architecture Salim Prasad
Some background About Primavera Systems Primavera is the largest independent provider of collaborative project, resource and portfolio management solutions. 20 year progress through technology Began with project management tools developed in DOS Currently has a large application suite for enterprise project, portfolio and resource management comprised of several applications written in Delphi and Java, client-server to J2EE This paper talks about transforming the Delphi Codebase (1.5 M lines) to enable agile development Prasad Salim
Where were we… Traditional waterfall development Requirements handed out in the beginning of the release cycle Isolated development where each programmer is assigned a feature Long release cycles with typical ping-pong game between testers and programmers Long work hours during last several months of the release cycle to finish up the features Salim – 1-2 Prasad – 3-4
Where were we… 1.5 M lines of code in Delphi, starting from Delphi 1.0 Runaway dependencies due to implicit includes Conditional compiler directives to create individual applications Event-driven programming model
Where are we… Introduction of Scrum in 2003 10-15 cross-functional teams Test Driven Development in 2004 Bob and Micah Martin, Michael Feathers Finally facing up to the Goliath 1-3 Prasad 4-5 Salim
Lesson 1 Refactoring legacy code cannot work in isolation Restating core agile principle Unity project – story of a brave man facing the challenges alone!!! “Lets rewrite this thing in parallel” – story of an ever missing train Prasad
Path to lesson 2: Refactor “Bad” code Task Calendar Mgr, the God Class Unit testing legacy code Salim Using interfaces for refactoring VirtualRow
Lesson 2 Legacy code is not bad code; just legacy code Tried to refactor legacy framework just because it was there Struggling with TDD Refactoring large legacy classes Prasad
Lesson 3 The epiphany: TDD the feature, not the legacy code Refactor just enough to write your test The epiphany: It is better to be simplistic All Animesh cared was how to write test for his feature!!! TDD the feature, not the legacy code If you feel the pain, change it. But, don’t be masochists Prasad – 1, 3 Salim – 2
Birth of Business Object Framework
Lesson 4 When you don’t know better, follow simple architectural principles Single responsibility Controlled linear dependencies Testability Salim – 1-2 Prasad - 3
Lesson 5 Each team contributed to BOF for their specific feature Agile development in a legacy framework can only work by evolution. Each team contributed to BOF for their specific feature Divide and conquer Evolve fully tested parallel frameworks to replace existing ones when needed Salim – 1, 3, 5 Prasad – 2, 3 Create formal ways to control dependency
Lesson 6 Incremental evolution and discrepancies Start refactoring bottom-up, followed by a periodic top-down review to unify the architecture Incremental evolution and discrepancies Finding patterns and emerging architecture Mentoring to conform Review and refactor Have a vision Prasad – 1- 3 Salim – 4-5
Where will we be… 100% of new features developed using TDD Use fit to create acceptance/functional tests below GUI Expand coverage of automated GUI acceptance tests Prasad, Salim