Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Anna Filina

January 29, 2016
Tweet

More Decks by Anna Filina

Other Decks in Programming

Transcript

  1. foolab.ca | @foolabca
    Rewriting

    12-Year-Old Code
    PHPBenelux, Antwerp - January 29, 2016

    View full-size slide

  2. Anna Filina
    • Developer
    • Problem solver
    • Teacher
    • Advisor
    • FooLab + ConFoo
    2

    View full-size slide

  3. You Inherited a

    15-Year-Old Codebase
    Code Doesn't Age Like Wine

    View full-size slide

  4. The web was 600 pixels wide
    4

    View full-size slide

  5. 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
    5

    View full-size slide

  6. Objectives
    • Reduce mistakes
    • Increase dev. speed
    • Reduce tech. debt
    • Avoid getting stuck
    • Increase confidence
    6

    View full-size slide

  7. Global functions
    include("functions.php");
    MyClass::myMethod(); // namespaced function?
    8

    View full-size slide

  8. False security
    $clean = htmlentities($_POST['input_field']);
    // use filter functions or a framework
    // use prepared statements
    9

    View full-size slide

  9. What happened at order 20117?
    if ($order_id > 20117) {
    // use this sql
    } else {
    // use that sql
    }
    // weakness = time to refactor
    10

    View full-size slide

  10. 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.
    11

    View full-size slide

  11. Complex call graph
    $instance = Model::getInstanceByCode($code);
    class Model
    {
    public static function getInstanceByCode($code)
    {
    //...
    $instances = Cache::getCache($cacheIndex);
    }
    }
    class Cache
    {
    public static function getCache($cacheIndex)
    {
    //...
    $cache = File::getFileContent($filePath);
    }
    }
    12

    View full-size slide

  12. Codebase
    • 5,000 classes.
    • 20,000 methods.
    • 1,500,000 lines of code.
    13

    View full-size slide

  13. Strategy
    • Make a strategy based on
    contraints
    • Full rewrite vs progressive
    ◦ By class
    ◦ By module
    ◦ By HTTP call
    • How to run code side-by-side
    ◦ Session sharing
    14

    View full-size slide

  14. Before You Code

    View full-size slide

  15. Data can be lost, stuff can break
    • Backup: test restore
    • Staging environment: app versions, configs
    • Simulate deployments/upgrades
    • Automate tests before code changes
    • Make a risk assessment
    ◦ Don't be too optimistic
    ◦ Account for side-effects
    16

    View full-size slide

  16. Refactoring Example

    View full-size slide

  17. 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)
    18

    View full-size slide

  18. Solution
    • Rewrite complex forms in Symfony
    ◦ mod_rewrite for concerned pages
    • Rewrite biggest module as OOP
    ◦ Design extraction
    ◦ Automated tests
    ◦ Flexible architecture
    19

    View full-size slide

  19. Design Extraction

    View full-size slide

  20. Avoid code bias
    • Old code → design docs
    • Validate design docs
    ◦ Clarify business rules
    • Improve design
    ◦ Reduce tech. debt
    ◦ More flexible
    • Design docs → new code
    21

    View full-size slide

  21. Code-Level Advice

    View full-size slide

  22. Infrastructure
    • Set up logging
    ◦ Monolog if PHP version allows
    ◦ file_put_contents if really old version
    • Set up testing
    ◦ Mocking static methods: Patchwork or equivalent
    ◦ Cache API call output (get the docs!)
    23

    View full-size slide

  23. Code duplication
    • Sometimes, the bug is repeated 80+ times
    • Remove duplications ASAP
    24

    View full-size slide

  24. Fix long methods
    • Extract broken part into its own method
    • Write unit tests for it
    • Fix it
    • Call it from the mega-method
    25

    View full-size slide

  25. More Stories

    View full-size slide

  26. ASP Classic to PHP 5.6
    • 15+ spaghetti and hacks
    • Language no longer supported
    • Huge ERP with lots of code
    27

    View full-size slide

  27. 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!
    28

    View full-size slide

  28. Guzzle tests
    29

    View full-size slide

  29. PHP 5.3 to PHP 5.6
    • 12+ spaghetti and hacks
    • Uses deprecated functions
    • Can't run on PHP 5.6
    30

    View full-size slide

  30. Solution
    • Split servers into 5.3 and 5.6 for fresh start
    • REST and modern design patterns
    • AngularJS frontend
    31

    View full-size slide

  31. Splitting the app
    32

    View full-size slide

  32. Alias is your friend (5.3 server)
    Alias "/module-name" "/var/www/project/angular"

    RewriteBase /module-name/

    33

    View full-size slide

  33. Try something new
    • Bounce ideas
    ◦ New people to avoid tunnel vision
    • Has this been done before?
    • Can I try another approach?
    35

    View full-size slide

  34. Ask refactoring experts
    • Pick their brain
    • Read their blog
    • Hire one for a day
    ◦ Refactoring strategy
    ◦ Remove roadblocks
    ◦ Guidance (one day per week to steer in right direction)
    36

    View full-size slide

  35. Takeaways
    • Plan before you act
    • Use known tools & methodologies
    • Get inspiration from others
    • Refactoring gets easier
    • Every problem has a solution
    37

    View full-size slide

  36. Anna Filina
    • Development.
    • Fix bugs & performance issues.
    • Workshops on testing, Symfony & API.
    • Advisor on testing strategy, legacy code.
    • Pluralsight freebies!
    38

    View full-size slide

  37. @afilina afilina.com
    joind.in

    View full-size slide