One of the most common recurring problems in software design is how to manage data flow in your code. Unless you use global variables for everything, you have to worry about this problem. Of course, if you do use global variables for everything, you have other problems.
Anyway, consider:
frob(arg1, arg2, arg3)...
Eventually, the number of parameters to a function may get unwieldy, and importantly, you may need to pass a number of those parameters to different subroutines called from frob. That gets hard to maintain, it's ugly, you forget which order the parameters go in, and it's generally a pain. People have probably given guidelines about how many parameters to a function is too many, but you don't need a rule like "7 is too many" to know when you have a problem.
So, the next step is to make arg1, etc. into fields of a record, and then pass the record around to different subs. But then you have a whole set of different problems. It can introduce another compile-time dependency (at least, in languages like C (Pascal too?): see John Lakos.), and you then you wind up writing extra code to initialize and return a record. Sometimes a function doesn't need everything in the record but you still wind up passing the whole thing in, and I could swear there's some "software rule" that explains how this increases the coupling between different pieces of code (can anyone remind me what it is?).
This is one of the things OO is meant to solve. Group pieces of code that need the same data together, figure out what abstraction that represents in your program, and then each method that accesses the data doesn't have to get it from anywhere else but its own object instance. Not that this solves all of your problems, of course, but it helps.
In languages that support further levels of program organization, there are other places to stick things. For instance, consider languages that have modules in addition to classes. There are yet more ways to abstract around data... closures, currying, continuations. What else?
And of course, you often have to figure out where to put your data. Where is the data created and initialized? Who "owns" it (who's responsible for freeing its memory, etc.)?
The problem of what you do with return values is yet another common issue.
This post feels incomplete and without purpose, but this bit from Adam (bottom part of the day) spurred me to write down some thoughts.
Feel free to post a comment below. Please see my comment policy.
Formatting Rules (No HTML):