I recently picked up a new book on object-oriented programming called “Object-Oriented Design Heuristics” by Arthur J. Riel. In the book, Riel explains programming’s natural evolution from procedures and data structures to object-oriented. He talks about how programmers adapted their development style to reduce the effects of changes to data structures.
In procedural programming, programmers develop software by decomposing a system into procedures (or functions) that act on a set of shared data structures. One of the problems associated with this type of programming is what Riel calls the “unidirectional relationship between data and behavior”. This unidirectional relationship means you can tell which data a procedure depends on by looking at the procedure (its parameters, local variables, and global variable access), but you can’t tell which procedures use a data structure by looking at the data structure. Take the following pseudocode for example: