Coding is an art. You can read Design Patterns and Object Oriented Programming tips all day long, but not until you start developing an elaborate project, will you realize that coding is an art. In my game engine, I have broken many coding rules. For example, the math engine does not use any setters or getters functions; the class members are Public. This is a big No, No in design.

I break coding rules when I see it fit, but I also abide by them as much as possible. One OOP rule which I always follow is:

Code to the Interface, not to the implementation.

This rule is paramount. It is what makes an application modular, flexible and maintainable. Another way to phrase this rule is:

Code to the Superclass, not the Concrete class.

For example, assume that Beagle and Pitbull are subclasses of a Dog class. Instead of coding to the implementation as shown below: