I'm reading a great book by Eric and Elisabeth Freeman at the moment on design patterns called Head First Design Patterns. I have been working with some fairly difficult to maintain code recently, so thought I would write about how the use of some simple design principles can make code a lot more flexible and therefore easier to maintain.
"Encapsulate what changes" is a core OO principle, but what does it mean? Encapsulation is the seperation of logic, encapsulating or hiding logic behind a defined interface. So encapsulate what changes means that if it's going to change, could change, or there are many variants of it - you should encapsulate it in an object. Identifying what can change is the tricky part.
A data layer I saw recently is a good example where this could be applied. It contained a method that was deleting a record and it's many (dozens) of child record collections. This method was >500 lines long, which is a sure indicator of a bad design! The bulk of the method was a large if-else statement that deleted the child collections. One of the issues with this design is that in order to add a new child collection, I had to change the original logic. By being forced to modify the body of the method I danced a waltz with regression (and put my name against the source control history of a 500 line static method!).
If the method had used composition and used a collection of objects (with a common interface type) to delete these child records, adding a new class to delete my new child records without modifying any of the existing logic would have been easy. It could have looked like this:

The key here is that the logic to delete the different child records (each child deletes from a number of different tables) is loosely coupled to the logic for deleting the parent. This means the logic for each child can be changed, added, removed or reused independently of the parent and each other child.