I've found it quite difficult to keep classes having only one responsibility. In programming _examples_ it is easy to see what the responsibility is and what is supposed to be another class' responsibility.
But programming large software systems the responsibilities are not apparent at start. You shape your abstractions and terminology for the software as you are writing it and as you find subtle details.
This problem is what got me sold on test-driven development: Actually writing a test for every method of a class clarifies so much about what the responsibility is, and what could be refactored out into a separate unit.
I cant explain it, but for me unit testing has become so much more of a thought tool while prototyping and developing than an actual testing tool once the code is written.
My hunch is that for writing testable code, you want to make interfaces small and simple, so you try to pinch them everywhere, to make unit tests simpler. As you do that you see what has very low (minimally required) coupling and thus can be separate units.
But programming large software systems the responsibilities are not apparent at start. You shape your abstractions and terminology for the software as you are writing it and as you find subtle details.
This problem is what got me sold on test-driven development: Actually writing a test for every method of a class clarifies so much about what the responsibility is, and what could be refactored out into a separate unit.
I cant explain it, but for me unit testing has become so much more of a thought tool while prototyping and developing than an actual testing tool once the code is written.
My hunch is that for writing testable code, you want to make interfaces small and simple, so you try to pinch them everywhere, to make unit tests simpler. As you do that you see what has very low (minimally required) coupling and thus can be separate units.