11 Follow the structure in the code

 

This chapter covers

  • Encoding behavior in the control flow
  • Moving behavior into data structures
  • Using data to encode behavior
  • Identifying unexploited structures in the code

Software is a model of an aspect of the real world. The real world changes as we learn and grow, and we need to adapt our software to encompass these changes. In this way, as long as the software is being used, it is never finished. This also means connections in the real world must be represented in our code: the code is a codified structure from the real world.

In this chapter, we first discuss where different types of code structure come from. Then we examine three different ways behavior can be embedded in code and how to move behavior between these approaches. Having established the types of structure we are dealing with, we discuss refactoring: when it is helpful and when it may be disadvantageous. Finally, we look at different types of unexploited structures and how to use them with the refactoring patterns we have learned.

11.1 Categorizing structure based on scope and origin

In software development, we deal with several types of structure (that is, recognizable patterns). Such a structure could be two similar methods or something people do every day. There is structure in the domain, structure in the program’s behavior, structure in our communication, and structure in the code.

11.2 Three ways that code mirrors behavior

11.2.1 Expressing behavior in the control flow

11.2.2 Expressing behavior in the structure of the data

11.2.3 Expressing behavior in the data

11.3 Adding code to expose structure

11.4 Observing instead of predicting, and using empirical techniques

11.5 Gaining safety without understanding the code

11.5.1 Gaining safety through testing

11.5.2 Gaining safety through mastery

11.5.3 Gaining safety through tool assistance

11.5.4 Gaining safety through formal verification

11.5.5 Gaining safety through fault tolerance

11.6 Identifying unexploited structures

11.6.1 Exploiting whitespace with extraction and encapsulation

11.6.2 Exploiting duplication with unification

11.6.3 Exploiting common affixes with encapsulation

11.6.4 Exploiting the runtime type with dynamic dispatch