Software Design for Flexibility (How to Avoid Programming Yourself into a Corner)