I think that maintainability is also tightly coupled with problem complexity, which can be a subjective matter. I've seen situations where the sole developer was able to successfully maintain and consistently grow a large code base, but when others step into his place, it appears an unmaintainable mess -- just because they have quite different mental models.
Patterns and practices really help (see other answers for great advice). However, their abuse can lead to even more problems when the original solution is lost behind facades, adapters and unnecessary abstractions.
In general, understanding comes with experience. A great way to learn is to analyze how others have solved similar problems, trying to find strong and weak points in their implementation.