1. Minimiza accessibility of classes and members.
2. Don't expose member data in public.
3. Don't put private implementation details in a class's interface
4. Favor read-time convenience to write-time convenience.
Code is read far more times than it's written, even during initial development.
5.Be very, very wary of semantic violaions of encapsulation.
Here are some examples of the ways that a user of a class can break encapsulation semantically:
Not calling Class A's initialize() routine because you know that Class A's performFirstOperation() routine calls it automatically.
Not calling the database.connect() routine before you call employee.retrieve(database) because you know that the employee.retrieve() function will connect to the database if there isn't already a connection.
The proble with each of these examples is that they make the client code dependent not on the class's public interface, but on its private implementation. Anytime you find yourself looking at a class's implementation to figure out how to use the class, you're not programming to the interface; you're programming through the interface to the implementation.
6. Watch for coupling that's too tight.
Design and Implementation Issues
Summary of when to use inheritance and when to use containment:
1. if multiple classes share common data but not behavior, then create a common object that those classes can contian.
2. if multiple classes share common behavior but not data, then derive them from a common base class that defines the common routines.
3. if multiple classes share common data and behavior, then inherit from a common base class that defines the common data and routines.
4. inherit when you want the base class to control your interface; contain when you want to control your interface.