But having a function called automatically no matter where your code is in it's execution is a better way to go.
Says who? I don't agree with that statement at all. Again, unless there is a critical need to act immediately on a character why not let the built-in interrupts handle it? Nick mentioned a buffer. Incorrectly he called it a 32-byte, when it is in fact 128 bytes. Regardless, interrupts already handle incoming bytes.
As long as interrupts are not disabled in loop(), everything just works nicely and loop() doesn't get so cluttered.
One option is:
That doesn't look very cluttered to me.