A common activity during software development is deciding when and how to functionally decompose your code. I take some liberty with the broad term functional decomposition here, and am specifically referring to *breaking down or refactoring larger functions or methods into smaller functions or methods*. At Atomic Object, we’ve sometimes referred to this practice as _rolling out the dough_.
Some reasons that drive me to start decomposing, and become my *when*, are:
* complicated unit tests
* the “single responsibility principle”:http://en.wikipedia.org/wiki/Single_responsibility_principle
* implementation readability
* refactoring for re-use of common code elsewhere
These are but a few of many reasons that provide us, as programmers, context for some much needed dough rolling. Lately I’ve been pondering *how* the next step should be taken given the options.
*An Aside*: At Atomic Object we write a good amount of our OO code in a functional style, where many of our classes are akin to a state-less module (instantiated as a non-enforced singleton) with one or a few methods defined on it. I find this approach useful when solving problems not directly related to data modeling, where thinking functionally feels more natural.
Once poised to break down a larger function, *how* do you approach it?
* Do you define a new private method or non-exported function?
* Would you make a new class or module with a public method or function to promote re-use within your project?
* Would you add a new public method or function to the same module, preferring categorized groups of functions over many small modules?
* How much does the context of decomposition matter to your decision?
h2. What I’ve done
Given a “functional” OO environment I’d usually default to making a new class with a public method. This feels like the cleanest approach to a scenario where I:
* can unit test the new function in the easiest way for the resulting implementation
* can produce a separation in the original implementation that’s easy to use interaction based testing on (mocks), if desired
* provide a publicly tested interface to the new function that can be used elsewhere
h2. What do you do?
Do you have a preferred approach for rolling out the dough in your language of choice?