foreach only works on a list. I can bless a list of lists into a rose tree, but i can't traverse that in a uniform way. There's just no hook to say, when the thing isn't a list, get the next element like this. Now days i'd point at haskell's traversable as the gold standard.
On large java projects it seems like composite/facade for days. Those splits seemed to let teams work together and not end up with piles of rubble.
A lot of my understanding of programmer fashion back then was pretty fuzzy. It was easy to ask any team if they were doing extreme programming and they'd all respond, well, kinda. Ask any team if they were using a pattern language, and they'd mumble about UML. Sort of the equivalent of well, kinda.
When you have to write a large project like a compiler or a web browser or something, it's handy to have around. All to often I stare at the empty text window in my ide and question my life choices. I wonder why i didn't learn to weld and why i'm a failure at everything i try. The existential dread fills my soul and i want to just crawl under my desk and cry. In that case, i'll flip through the GoF. Then i tell that endless abyss "I'm going to use the Command Pattern!" The abyss slinks back into the corner quietly murmuring until i feed it a couple beers at the end of the day.
On the other hand, i did quite a bit of perl programming around 2000, so i'm probably weird.