Rewriting 15-Year-Old Code

Rewriting 15-Year-Old Code

B3b2139e4f2c0eca4efe2379fcebc1c5?s=128

Anna Filina

October 17, 2017
Tweet

Transcript

  1. 2.

    Anna Filina • Project rescue expert • Legacy fixer •

    Developer • Conference speaker • Trainer
  2. 5.

    Feeling Old Yet? • Y2K bug. • Internet Explorer 5.

    • ICQ was starting to be cool. • Rounded corners = status symbol.
  3. 7.

    Mixed Concerns <% products = Product.all total = 0 products.each

    do |product| total += product.qty * product.price end %> <p>Total: <%= total %></p>
  4. 10.

    Inexplicable Conditions if order_id > 20117 # use this sql

    else # use that sql end # weakness = time to refactor
  5. 11.

    Long Methods public function importCsv($path, $googleApiKey, $databaseDsn, $databaseUser, $databasePassword) {

    // Convert CSV to array of conferences $lines = file($path); $csv = array_map('str_getcsv', $lines); $conferences = []; foreach ($csv as $line) { $conference = new Conference(); $conference->name = $line[0]; $conference->location = $line[1]; $conferences[] = $conference; // Get coordinates for location $location = urlencode($conference->location); $url = 'https://maps.googleapis.com/maps/api/geocode/json?address='.$location.'&key='.$googleApiKey; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($curl); curl_close($curl); $json = json_decode($response); if (count($json->results) == 0) { continue; } $latitude = $json->results[0]->geometry->location->lat; $longitude = $json->results[0]->geometry->location->lng; $coordinates = $latitude.','.$longitude; $conference->coordinates = $coordinates; // Save conference to database $pdo = new PDO($databaseDsn, $databaseUser, $databasePassword); $statement = $pdo->prepare('REPLACE INTO conference (name, location, coordinates) VALUES (?, ?, ?)'); $statement->execute([ $conference->name, $conference->location, $conference->coordinates, ]);
  6. 12.

    Average Legacy Code File • 3000-6000 lines of code. •

    Half of it is commented "in case we need it later". • Method length of 800 lines. • Abuse of helper classes. • Sometimes no classes at all.
  7. 15.

    Strategy • Make a strategy based on constraints. • Full

    rewrite vs progressive: ◦By class. ◦By feature. ◦By HTTP call. • How to run code side-by-side: ◦DB/Session sharing. ◦mod_rewrite.
  8. 16.

    Data Can Be Lost, Stuff Can Break • Backup: test

    restore. • Nullify sensitive data. • Staging: simulate deployments/ upgrades/batch processes. • Automate tests before code changes. • Make a risk assessment: ◦ Don't be too optimistic. ◦ Account for side-effects.
  9. 19.

    PHP 3 to PHP 5.6 • HTML + PHP +

    SQL in same file. • Includes all over the place. • IFs that concatenate SQL. • Previous rewrite attempt: ◦ Failed, made things worse. ◦ Folders of dead code. ◦ Classes with static functions (no instances).
  10. 20.

    Solution • Rewrite complex forms using a framework: ◦ mod_rewrite

    for concerned pages. • Rewrite biggest feature as OOP: ◦ Design extraction. ◦ Flexible architecture. ◦ Automated tests.
  11. 23.

    Avoid Code Bias • Old code → design docs. •

    Validate design docs: ◦Clarify business rules. • Improve design: ◦Reduce technical debt. ◦More flexible. • Design docs → new code.
  12. 26.

    Fix Long Methods • Extract broken part into its own

    method. • Write unit tests for it. • Fix it. • Call it from the mega-method.
  13. 27.

    Spot Logical Groups Code block Comment Code block Comment Convert

    CSV to array of conferences. Get coordinates for conference location. Save conference to database. Code block Comment
  14. 29.

    Name Code block Method Code block Method Call method Call

    method Code block Method Call method conferences_from_csv location_coordinates save_conference
  15. 31.

    ASP Classic to PHP 5.6 • 15+ spaghetti and hacks.

    • Language no longer supported. • Huge ERP with lots of code.
  16. 32.

    Solution • Rewrite page by page to a framework. •

    mod_rewrite for concerned pages. • DB session adapter in both apps. • Page in any language = HTTP request. ◦ Automated testing possible!
  17. 34.

    On Testing Before you code You better test So that

    on weekends You may rest. -- Me
  18. 35.
  19. 36.
  20. 37.

    Try Something New • Bounce ideas. ◦ New people to

    avoid tunnel vision. • Has this been done before? • Can I try another approach?
  21. 38.

    Takeaways • Make a strategy. • You touch it, you

    refactor it. • Use known tools & methodologies. • Get inspiration from others. • Refactoring gets easier. • Every problem has a solution.