People generally learn by forming patterns from many examples, not by studying the patterns themselves. Attempts to directly communicate abstract patterns generally fails (any school anywhere: "this is boring because we are never going to use it").
Programmers are inherently attracted to building on imperfect abstractions, because that brokenness is something to latch on and set about easily solving (as it's been solved many times before and they don't even need to solve it perfectly). If the abstraction did exactly what they wanted, they would have to recognize that, understand what was given to them, and then confront the essential complexity of their problem that much sooner.
http://www.jwz.org/doc/worse-is-better.html