A good program should be flexible to handle changes without rewriting, user friendly by interacting through understandable messages, portable by running on different platforms with minimal changes, reliable to perform accurately despite small system changes and handle unexpected situations, and have self-documenting code through properly named variables and methods.