Skip to content

FrOSCon - Fixing Legacy Code

By Benjamin Eberlei and Kore Nordmann.

What Is Legacy Code

  • hard or impossible to fix errors or implement new features
  • hard or impossible to implement automatic testing

What Is The Talk About

Issues With Legacy Code

  • code issues
  • inversion of control
  • data structures
  • application or business logic
  • shared state

Code Issues

  • code size
  • high efferent coupling
  • code duplication
  • ...
  • Use phpmd to locate size or complexity errors.

Efferent Coupling

  • many outgoing coupling for one class in other classes
  • can be located with pdepend

Inversion Of Control

  • Missing abstractions
  • Inline new
  • Static calls
  • Inline life cycle management (only value objects and exceptions should be newed inline)

Data Structure

  • Missing abstractions
  • Inline new
  • Static calls
  • Inline life cycle management (only value objects and exceptions should be newed inline)

Data Structure

  • with arrays, you have a bad documentation
  • use simple value objects (also known as dto) and they are not immutable
  • split logic and try to avoid big models (seperation of concerns (roles/contextes) on model logic
  • branch by abstraction
    • introduce facade / proxy for old code
    • call old code from facade / proxy implementation
    • write new shiny facade / proxy implementation
    • use new implementation
    • delete old code

Application Or Business Logic

  • mixed business logic (application logic) in large controllers is the most common and pressing issue with legacy code (fat controllers)
  • try to use solutions like business requirement
  • extract business logic like service layer pattern
  • introduce (domain) events (in the same request)
  • introduce message queues (not in the same request)

Shared State

  • we know that global state is bad
  • sessions are (often) cross-request global state in bash maps
  • method execution pathes depending on current object state are horrible to track down

Testing Changes

  • if your legacy code is hard to test, try to test it from the http protocoll point of view
  • use behat as behaviour driven development (BDD)
  • use mink with "goute", "sahi" or "zombie.js", "selenium", "selenium 2"

Extra

  • do small checks when refactoring (good indicator are many, many commits)
  • test your primary use cases (put the chaos in the cage)
  • be bold (enough) and remove old code