How to keep flat faces flat when using smooth shading
If I got your question right, I think you should use a "subdivision surface" modifier, and smooth shading, to get what you want. Just add some edge on the cylinder top face and side surface, quite near the loop that divides them...

See below images:




or, for the cube version: