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

Rewriting Legacy Code

Rewriting Legacy Code

Video: https://youtu.be/bTuvjjtGipY

Did you ever have to maintain a 20-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 pick the right rewrite strategy, and how to overcome other challenges that arise from dealing with legacy.

Anna Filina
PRO

May 13, 2020
Tweet

More Decks by Anna Filina

Other Decks in Technology

Transcript


  1. Rewriting
    Legacy Code
    THE LEGACY OF SOCRATES | MAY 13, 2020
    @afilina

    View Slide

  2. Anna Filina
    ‣ Coding since 1997.
    ‣ Legacy archaeology.
    ‣ Test automation.
    ‣ Talks and workshops.
    ‣ YouTube videos.

    View Slide

  3. You Inherited a

    10-Year-Old Codebase

    View Slide

  4. You Inherited a

    15-Year-Old Codebase

    View Slide

  5. You Inherited a

    20-Year-Old Codebase

    View Slide

  6. View Slide

  7. Web in 2000
    ‣ Y2K bug.
    ‣ Internet Explorer 5.
    ‣ ICQ was starting to be cool.
    ‣ Background music.
    ‣ Rounded corners = status symbol.

    View Slide

  8. Legacy Sadness

    View Slide

  9. The Methods
    ‣ Can easily exceed a thousand lines.
    ‣ Mixing SQL, PHP and HTML.
    ‣ Receiving dozens of arguments of arbitrary type.
    ‣ Accessing hundreds of potentially undefined properties.
    ‣ Expect properties to have been set by a child 10 method calls ago.
    ‣ methodName_new, methodName_new2

    View Slide

  10. The Dynamic Types
    ‣ Null pointer exceptions of every flavor.
    ‣ Attempting to split an array.
    ‣ Attempting to divide by a null.
    ‣ Attempting to count the number of elements in a float.
    ‣ Attempting to max($array1, $array2),

    where array items are of mixed types.

    View Slide

  11. How to Fail a Rewrite

    View Slide

  12. Microservices
    AWS
    GitHub
    React
    CircleCI
    ElasticSearch Ansible
    Docker
    Symfony
    Ambitious new tech stack

    View Slide

  13. Other Ambitions
    ‣ SOLID.
    ‣ Test-driven development.
    ‣ Strong typing.
    Too many new things at once

    View Slide

  14. Expanding Scope
    ‣ Rethinking existing features.
    ‣ New features.
    ‣ New work methodology.

    View Slide

  15. Start With the Strategy

    View Slide

  16. Strategy
    ‣ Version upgrade.
    ‣ New framework.
    ‣ Progressive rewrite.
    ‣ Refactoring only.
    ‣ Full rewrite.

    View Slide

  17. Version Upgrade
    ‣ PHPCodeSniffer can detect incompatibilities.
    ‣ Some libs might be easier to swap than to fix (PHPExcel).
    ‣ Regexes are your friends.
    ‣ Rector can automatically refactor.
    ‣ Need to freeze development.

    View Slide

  18. View Slide

  19. New Framework
    ‣ Use dependency injection.
    ‣ Automate large chunks with Rector.
    ‣ Use adapters.
    ‣ Need to freeze development.

    View Slide

  20. Product/IndexHandler
    ProductController
    indexAction
    viewAction
    Product/ViewHandler
    Routes
    Routes
    Product/BaseHandler
    Example: Zend Framework 1 to Zend Expressive

    View Slide

  21. class IndexHandler extends BaseHandler implements RequestHandlerInterface
    {
    public function __construct(
    TemplateRendererInterface $template,
    ProductModel $productModel
    ) {
    //...
    }
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
    return new HtmlResponse(

    $this->template->render('admin::product/index', $view)

    );
    }
    }

    View Slide

  22. Progressive Rewrite
    ‣ By class.
    ‣ By module
    • Can switch language.
    • Use design extraction.

    View Slide

  23. Old Code
    New Design
    Old Design
    New Code

    View Slide

  24. ‣ Some criteria for refactoring:
    • Need to change.
    • Hard to understand, but need to work with it.
    Refactoring Only

    View Slide

  25. Full Rewrite
    ‣ Discouraged.
    ‣ My criteria:
    • Can disregard existing features.
    • Few or no integrations.
    • Can trash old database.
    • If not, need a team experienced in full rewrites.

    View Slide

  26. Spot Problems Early
    ‣ PHPStorm inspections.
    ‣ Pslam: start with auto-detected level.

    View Slide

  27. Unknown
    Unknowns

    View Slide

  28. Docs
    ‣ No docs.
    ‣ Too many, little relevance.
    ‣ Outdated or misleading.

    View Slide

  29. Tests
    ‣ No tests.
    ‣ Not runnable.
    ‣ Failing.
    ‣ Brittle: specific environment or inter-dependencies.
    ‣ Unreliable.

    View Slide

  30. Dead Code
    ‣ Unused endpoints.
    ‣ Commented-out code.
    ‣ Unused classes or methods: exercise extreme caution.
    ‣ Merge duplicated code (bug repeated 80 times).

    View Slide

  31. Testing Approaches

    View Slide

  32. Version Upgrade
    Smoke tests Fix code
    Should work

    for old and new
    versions.
    Unit tests

    View Slide

  33. New Framework
    Smoke tests Migrate
    Should work

    for old and new
    versions.
    Unit tests

    View Slide

  34. Progressive Rewrite
    For new code only.
    Acceptance tests Unit tests
    Should work

    for old and new
    versions.
    New code

    View Slide

  35. Refactoring Only
    For the code that
    you want to write.
    Acceptance tests Unit tests
    Should work

    for old and new
    versions.
    Refactor

    View Slide

  36. Preparing the
    Environments

    View Slide

  37. Local Environment
    ‣ Docker.
    ‣ Baseline image.
    ‣ Migration image.
    ‣ Match server / vagrant.

    View Slide

  38. services:
    php: //...
    mysql: //...
    acceptance: //...
    mysql_test: //...

    View Slide

  39. Gotchas
    ‣ Pay attention to MySQL mode.
    ‣ Run composer inside Docker, commit composer.lock
    ‣ Anonymized production database.
    ‣ Send e-mails to relay: DebugMail, MailTrap, etc.

    View Slide

  40. Staging Environment
    ‣ Baseline server.
    ‣ Migration server.
    ‣ Staging config: point to sandboxes.

    View Slide

  41. Credit: xebia.com

    View Slide


  42. THANKS!
    @afilina

    View Slide