| C# often has "release valves" that allow you to divert from some of the mess that Java tends to exhibit. `events` and `delegates` from C# 1/.NET 1, flawed as they may be in retrospect, alone simplify several major patterns that Java falls into. I also think on the paradigm issue here is Java architects seem more inclined to have a "ravioli code" problem. There's an ancient Java ideal of componentization [1] that a lot of Java code tries to live up to. Lots of little components boxed into tight containers that only ever interact through often "reconfigurable" sauce: ravioli. There are some benefits to that ideal, it exists because it has some merits in terms of component testing, in particular. It's just that as with spaghetti code and copypasta code, ravioli code also sometimes winds up in a mess where the ideal meets the real world, and somehow a toddler (or junior developer in this analogy?) has thrown it all over the kitchen and you have no idea how to clean it up without destroying the entire kitchen and starting over... May not be a great analogy. ;) I'd argue that you are more likely to see Java-style ravioli code in C# projects that use IoC containers of one sort or another. Again, there's nothing particularly wrong with IoC containers [2] as an idea connected to some ideals of component testing, it's just that it's an ideal that often falls down and fails to deliver its advantages in the real world. [1] That somewhat resembles the Smalltalk ideal of object message passing while the language itself lacks much of the architecture for that. Arguably, a lot of Java's worst problems come from trying to replicate a lot of Smalltalk ideas and design patterns in a language that is nothing at all like Smalltalk and misses some important characteristics of Smalltalk. [2] IoC Containers are a ravioli concept directly imported to C# from the Java world, with the earliest IoC containers such as Spring.NET being Java ports. |