I agree with your first part entirely. As for the comments about math I look at it this way. Math can usefully be described as a nothing but a bunch of design patterns, discovered and built in just the way you say. Look at the way addition and multiplication morph into a ring, once you learn a little math. Dynamic programming algorithms then work for any ring.
The frustrating thing for programmers is that these patterns don't often seem to be directly useful in computer science. Oops, I mean programming.
I think that is changing thanks to functional languages. One of the most mind blowing CS lessons I learned in the past few years was how to calculate the derivative of a data structure and what to use it for, using plain old calculus rules. Now that might seems useless or crazy if you haven't studied algebraic data types. But these are readily seen to be useful once you learn a little math (and Haskell). In a few years I believe that FP will be credited for the wholesale import of mathematical design patterns into everyday programming. The Haskell and related communities are still small enough that they have only scratched the surface.