Kent Beck has a series of articles, describing various origins of objects, "Objects from States", "Objects from Variables", "Objects from Collections", "Objects From Methods".
I think it's an interesting question, and Kent Beck didn't exhaust it.
One rule of thumb which I think is present (at least implicitly?) in Bob Martin's Clean Code, and I have heard expressed more explicitly by J.B. Rainsberger, is that improving code often means taking something described as "mostly X, but a little Y", and refactoring to make it "just X".
Let's imagine a class described as "mostly just wires together a few things", and let's further imagine that we have already refactored it into "startling purity". After this refactoring, it might look like this:
class Wiring {
public:
Wiring(Foo* f) :
bar(f),
baz(&bar, f),
qux(&baz)
{
}
void Do() {
qux.Do();
}
private:
Bar bar;
Baz baz;
Qux qux;
};
In the course of refactoring it from "mostly" to "purely", we spun off some residue into a new class. Let's speculate about what that residue might have been. Was it that we only sometimes do?
if (quux.Test()) {
baz.Do();
}
Alternatively, was it that we repeatedly do?
while (not quux.Done()) {
baz.Do();
}
Or was it that we had a little chain going on?
baz.Do(quux.Get());
Each of these "surds" (and many more that I have not listed here) are perfectly good objects. I would love to connect them to, say, Erik Meijer's Rx, providing fictitious origin stories for each Rx stream combinator.