Rewriting 12-Year-Old Code

Rewriting 12-Year-Old Code

Did you ever have to maintain a 12-year-old application? Dead code and tables everywhere, static methods, database queries in between HTML tags and some pages still in PHP3. This presentation will lead you through a progressive rewrite from very old legacy to the latest shiny version of PHP. Learn how to automate legacy testing, how to seamlessly jump between the old and new parts, and how to overcome other challenges that arise from dealing with a codebase that was written in 2003.

B3b2139e4f2c0eca4efe2379fcebc1c5?s=128

Anna Filina

August 23, 2015
Tweet

Transcript

  1. foolab.ca | @foolabca Rewriting
 12-Year-Old Code FrOSCon, Sankt Augustin -

    August 23, 2015
  2. Anna Filina • Developer • Problem solver • Teacher •

    Advisor • FooLab + ConFoo 2
  3. You Inherited a
 10-Year-Old Codebase

  4. You Inherited a
 12-Year-Old Codebase

  5. You Inherited a
 15-Year-Old Codebase

  6. You Inherited a
 15-Year-Old Codebase Welcome to The Big Leagues

  7. Feeling old yet? • Y2K bug • Google launched AdWords

    • There was no Twitter, no Facebook, no iTunes • Internet Explorer 5 • ICQ was starting to be cool • Rounded corners = status symbol 7
  8. The web was 600 pixels wide 8

  9. Objectives • Reduce mistakes • Increase dev. speed • Reduce

    tech. debt • Avoid getting stuck • Increase confidence 9
  10. Code Smells

  11. You can never remember these names CREATE TABLE users; CREATE

    TABLE customer; CREATE TABLE userprofile; CREATE TABLE serveur; CREATE TABLE serveur_network; 11
  12. Giving you a false sense of security $clean = htmlentities($_POST['input_field']);

    12
  13. OOP, but with global & static functions include("functions.php"); 13

  14. What happened at order 20117? if ($order_id > 20117) {

    // use this sql } else { // use that sql } 14
  15. The Dangers of Refactoring

  16. It can take too long • Make a strategy •

    Opt for progressive refactor/rewrite • New code can run side-by-side ◦ Session: sharing/permissions/deadlocks ◦ Same or different prog. language ◦ mod_rewrite, mod_alias, etc. 16
  17. Data can be lost, stuff can break • Backup •

    Staging environment • Simulate deployments/upgrades • Automate tests • Make a risk assessment 17
  18. How Much to Change?

  19. Could be all of it • I always start with

    a framework • Start with small changes ◦ Learn the code ◦ Dive deeper ◦ Make bigger changes 19
  20. Remain pragmatic • Don't be zealous • Change needs to

    contribute towards objective • Database schema ◦ Need migration scripts ◦ Watch your footprint 20
  21. Stories

  22. Magento 1.5 to 1.9 • Auto database upgrade fail •

    Someone made manual changes to schema 22
  23. Solution • Fresh 1.9 install + plugins • Generate upgrade/downgrade

    patch ◦ Schema Sync (Python script) ◦ Insert missing eav_attribute entries ◦ Minor template tweaks 23
  24. PHP3 to PHP5.6 • HTML + PHP + SQL in

    same file • Includes all over the place • IFs that concatenate SQL • Previous rewrite attempt ◦ Failed ◦ Folders of dead code ◦ Classes with static functions 24
  25. Solution • Rewrite complex forms in Symfony • Rewrite biggest

    module as OOP ◦ Design extraction ◦ Automated tests • mod_rewrite for concerned pages 25
  26. Design Extraction

  27. Avoid code bias • Old code → design docs •

    Validate design docs ◦ Clarify business rules • Improve design ◦ Reduce tech. debt ◦ More flexible • Design docs → new code 27
  28. More Stories

  29. ASP Classic to PHP5.6 • 15+ spaghetti and hacks •

    No longer supported • A lot of code (gazillion of lines) 29
  30. Solution • Symfony to rewrite page by page • mod_rewrite

    for concerned pages • DB session adapter in both apps • Page in any language = HTTP request ◦ Guzzle tests FTW! 30
  31. Guzzle tests 31

  32. PHP5.3 to PHP5.6 • 12+ spaghetti and hacks • Uses

    deprecated functions • Doesn't run on PHP5.6 32
  33. Solution • Split servers into 5.3 and 5.6 for fresh

    start • REST and modern design patterns • AngularJS frontend ◦ Runs on 5.3 server, calls 5.6 API ◦ Forwards authorization headers 33
  34. Splitting the app 34

  35. Alias is your friend Alias "/module-name" "/var/www/project/angular" <Directory "/var/www/project/angular"> RewriteBase

    /module-name/ </Directory> 35
  36. How To Not Get Stuck?

  37. Plan • Start small • Make a roadmap • Don't

    skip the design stage 37
  38. If stuck • Bounce ideas ◦ New people to avoid

    tunnel vision • Has this been done before? • Can I try another approach? • Do I really need this change? 38
  39. Ask refactoring experts • Pick their brain • Read their

    blog • Hire one for a day ◦ Refactoring strategy ◦ Remove roadblocks ◦ Guidance (one un-stucking day per week) 39
  40. Practice creative thinking • Literature on "creative thinking" • Step

    away from the monitor ◦ Whiteboards ◦ Bean bags ◦ Lunch outside • Look at how non-devs solve similar problems 40
  41. Takeaways • Get inspiration from others • Refactoring gets easier

    • Use known tools & methodologies • Practice creative thinking • Every problem has a solution 41
  42. Anna Filina • Development: PHP, JS, etc. • Fix problems:

    bugs, performance, etc. • Workshops: testing, Symfony, AngularJS, API, etc. • Advisor: testing strategy, legacy code, etc. 42
  43. @afilina afilina.com