chapter nine

9 Refactoring towards Data

 

This chapter covers

  • Refactoring towards data orientation
  • Drawing boundaries with data
  • Writing good utility functions

Most codebases won’t be written in a data-oriented fashion (at least not yet). They’ll be the usual mix of object-oriented and imperative styles. Worse, no one will hand us “data-oriented requirements” or tell us to implement something in a “data-oriented way.” It’s up to us to tug codebases in the direction we want them to go. This means refactoring. We have to find the data hidden in everyday code and bring it to the surface.

This chapter is a guided tour of that refactoring process. It’s the culmination of all the techniques we’ve explored throughout this book. We’re going to take a messy object-oriented(ish) codebase and slowly refactor it towards a clean, data-oriented one. Trading objects for data makes these refactors small and incremental. We don’t have to solve everything at once. The right data type makes all the difference.

Throughout this process, we’ll flex the modeling and correctness skills we’ve learned, but we’ll also explore new ways of viewing what our data modeling means. We’re going to climb to the top of the ivory tower to explore something called the Curry-Howard correspondence. This vantagepoint will enable us to draw powerful boundaries that move even the messiest codebase towards one that’s simple, descriptive, and correct.

There’s a lot to explore, and it all begins with data.

Let’s get started!

9.1 A messy starting point

9.2 Analyzing common problems in code

9.2.1 Messy data modeling

9.2.2 Uncontrolled mutation

9.2.3 Sequential coupling

9.2.4 Hidden knowledge, partial construction, and shotgun validation

9.3 Fixing the problems

9.3.1 Work backwards from invariants

9.3.2 Draw boundaries with data

9.3.3 Make validation about evidence, not errors

9.3.4 Write utilities that make data-oriented programs more expressive

9.3.5 Keep mutation where useful, but use it to build data

9.3.6 Now consider object boundaries

9.4 Some encouragement on refactoring legacy code

9.5 Wrapping up

9.6 Summary