CodePark/ questions / Code smells & refactoring
START PRACTICINGPRACTICE
Backend question · Software design & patterns › Code smells & refactoring

You inherit a 3,000-line OrderService with 40 methods, few tests, and it runs in production. How do you refactor it safely?

First, build a safety net. Before you change anything, write characterization tests. These tests record what the code does today through its public methods, including any odd behaviour.

Then work in small steps that don't change behaviour. Commit each step, and make each one safe to deploy:

  • Group the methods by responsibility (pricing, payment, fulfilment, notifications). Check which fields each group uses.
  • Use Extract Class to move one group that belongs together into its own class.
  • Keep OrderService passing calls on (delegating) to the new class, so callers don't change.
  • Run the tests after every step.
  • Move business rules into the domain objects where they belong.
  • When all callers use the new classes, remove the delegating methods.

Don't mix refactoring and feature changes in the same commit. Don't try a big-bang rewrite (replacing everything at once). For a large legacy area, use the strangler fig approach: send new behaviour to new code, and move old paths over slowly until you can delete the old service.

  • Write characterization tests before any change.
  • Work in small steps that keep behaviour the same, and make each one deployable.
  • Extract related groups into classes, and let the old service delegate to them at first.
  • Keep refactoring separate from feature work.
  • Avoid big-bang rewrites, and use the strangler fig approach for large legacy parts.