Wow, I'm now 38 and recall falling in love with Rails at the age of 28. I was battling with .NET WebForms at the time, Rails was a breath of fresh air. Martin Fowler got me into Ruby about 6 months before Rails popped up. I still write Ruby + Rails almost every day.
Oddly, I'm starting to think Java might be the future of everything if it can shed it's huge_config.xml + FactoryFactoryFactory obsession, which I believe is happening :)
This is something that, knowing at thing or two about OOP but not being a java pro at all, I've recently come to wonder about: why does Java use all this Factories of Factories ? I mean where does this coding pattern come from? What aspect of the language it represents? Is it because of multi inheritance? Why then in other multi inheritance OOP languages this doesn't happen as much as in Java ?
I don't pretend to know the answer to this, but I can share when I've been tempted to do such things in Java.
You know how fairly often when writing OO code you want to have an object that takes a bunch of optional inputs in its constructor? That's trivial in Ruby because you can just stick those in a hash, merge the defaults with that hash and you have your options. In Java that won't work because you don't have syntactic sugar for default arguments and the syntax for creating maps is... complex. So you naturally think you need one place to handle all of the complexity of constructing the object and then you think of the factory pattern and you apply it.
Imagine, though, that some of the objects you use in order to construct the object you now have a factory for also become similarly difficult to construct. You don't want your existing factory to know about the complexity of how to construct those, so one idea would naturally be to offload their construction to something else, which passes them into your original factory. It's not a huge leap to then figure out you can put this in another factory and now you have a factory of factories. Repeat.
I'm sure there are other reasons why, but for me that's the most common one. When I used to write a lot of Java, I used to often have to resist the temptation to do that.
I hope what I wrote makes at least a little bit of sense...
I think the FactoryFactoryFactory-(anti)-pattern and bloated xml-configs are an enterprise thing, that by accident became a java thing (as java was adopted by people that were used to fighting with multi-kloc-c++ code-bases).
Another (related) java culture mis-feature is the tendency of "horizontal abstraction". Rather than building useful abstractions, there seems to be a tendency to move parameters from (initialization) code to xml to ini-files that generate xml to... All the while not really building up vertical abstractions where there sits something simple on top -- but rather just shifting the complexity "sideways" -- moving it around rather than collecting and simplifying.
I think part of this started before generics were introduced, as an artefact of java being a "compiled" language without any dynamic code-generation. So everyone ended up writing their own, strange, meta-programming language based on XML. Which can be fun as an exercise[1], but pretty poor in terms of tooling/ecosystem.
What java probably needed from the start was something like groovy -- and yes, my impression is that the ecosystem is becoming more sane.
BTW, java doesn't have multiple inheritance (well, it might have now that you can add some (static)code to interfaces[2]) -- it has (weak) contract based programming (via interfaces).
What java probably needed from the start was something like groovy
Jython (then called JPython) came along fairly early, in 1997 and feature complete but never took off for testing or gluing Java code. Jacl, a Java version of Tcl, also came around 1997 but virtually no one used it. Beanshell was built before Groovy, removing static typing but keeping the rest of Java's syntax. Groovy duplicated Beanshell's use case but brought closures and terse collections syntax, but didn't get any significant users until the Grails project spent a year (2006) retrofitting it with a meta-object protocol so it could be used with Grails. A second growth spurt happened in 2009 when Groovy added a DSL syntax to its already klunky grammar so Gradle could use it. Though you could argue Groovy's use in Gradle builds isn't very significant because the build files are typically 20 to 50 lines long, using the DSL syntax only and not making any use of the actual Groovy language features. And Gradle may not use Groovy as a build language for much longer. Calling Groovy an "overhead in the IDE-to-Gradle communication", the recent Gradle 2.0 roadmap [1] says:
"Android Studio demonstrates the enormous potential of a deep integration between the IDE and Gradle. At the moment, the price we pay for this is often mediocre responsiveness: every time the IDE makes a query of Gradle, the configuration phase is run before an answer can be given. The folks at Google are implementing some smart workarounds for this. But what is ultimately needed is a fundamental solution within Gradle that eliminates the overhead in the IDE-to-Gradle communication."
I should perhaps have been a little more clear: I didn't mean to imply there were no scripting languages for java, just that they weren't first-class citizens of the platform (Beanshell being an exception -- but perhaps it too suffered from being a bit heavy?).
It's interesting that Gradle seem to be moving away from Groovy -- especially considering the section on configuration: It appear they're moving towards a functional-flavoured architecture -- and at the same time further specializing Gradle -- so that it'll (probably) be a better build tool -- but also quite useless for other tasks/customization. Or rather; it would appear the project will not be much of a driver in improving Groovy for projects that need some form of dynamic configuration etc.
On the other hand Gradle will (presumably) serve as nice architectural model to follow for other projects (move towards a functional style, rather than programming dependencies in a procedural manner with a hacked up xml dialect).
Perhaps one of the core issues have been projects mixing complex configuration requirements (eg: routing for tomcat) with simple requirements (eg: username/password etc -- stuff that works well in a ini-like format). I suppose that if you've determined you need complex/powerful configuration, you'd be hard-pressed to include a second form of configuration in your project. After all simple xml files are almost as readable and easy to work with as ini-files... And yet, for a lot of projects, it's ended up being a bit of a mess.
I think this pattern was popularised in the Design Patterns book (Gama et al).
But my guess it's a natural progression from a standard Factory; Factories allow instantiation without specifying any type, and FactoryFactories afford the same flexibility, but just for instantiating a Factory without knowing it's type.
This was probably reenforced by the fact that life was easier if you built to interfaces rather than implementations, so factories were good for this.
I actually love the design patterns book, but I sometimes curse it - especially when stumbling upon things like the AbstractSingletonProxyFactoryBean. WTF!
Comments
Wow, I'm now 38 and recall falling in love with Rails at the age of 28. I was battling with .NET WebForms at the time, Rails was a breath of fresh air. Martin Fowler got me into Ruby about 6 months before Rails popped up. I still write Ruby + Rails almost every day.
Oddly, I'm starting to think Java might be the future of everything if it can shed it's huge_config.xml + FactoryFactoryFactory obsession, which I believe is happening :)
This is something that, knowing at thing or two about OOP but not being a java pro at all, I've recently come to wonder about: why does Java use all this Factories of Factories ? I mean where does this coding pattern come from? What aspect of the language it represents? Is it because of multi inheritance? Why then in other multi inheritance OOP languages this doesn't happen as much as in Java ?
I don't pretend to know the answer to this, but I can share when I've been tempted to do such things in Java.
You know how fairly often when writing OO code you want to have an object that takes a bunch of optional inputs in its constructor? That's trivial in Ruby because you can just stick those in a hash, merge the defaults with that hash and you have your options. In Java that won't work because you don't have syntactic sugar for default arguments and the syntax for creating maps is... complex. So you naturally think you need one place to handle all of the complexity of constructing the object and then you think of the factory pattern and you apply it.
Imagine, though, that some of the objects you use in order to construct the object you now have a factory for also become similarly difficult to construct. You don't want your existing factory to know about the complexity of how to construct those, so one idea would naturally be to offload their construction to something else, which passes them into your original factory. It's not a huge leap to then figure out you can put this in another factory and now you have a factory of factories. Repeat.
I'm sure there are other reasons why, but for me that's the most common one. When I used to write a lot of Java, I used to often have to resist the temptation to do that.
I hope what I wrote makes at least a little bit of sense...
I think the FactoryFactoryFactory-(anti)-pattern and bloated xml-configs are an enterprise thing, that by accident became a java thing (as java was adopted by people that were used to fighting with multi-kloc-c++ code-bases).
Another (related) java culture mis-feature is the tendency of "horizontal abstraction". Rather than building useful abstractions, there seems to be a tendency to move parameters from (initialization) code to xml to ini-files that generate xml to... All the while not really building up vertical abstractions where there sits something simple on top -- but rather just shifting the complexity "sideways" -- moving it around rather than collecting and simplifying.
I think part of this started before generics were introduced, as an artefact of java being a "compiled" language without any dynamic code-generation. So everyone ended up writing their own, strange, meta-programming language based on XML. Which can be fun as an exercise[1], but pretty poor in terms of tooling/ecosystem.
What java probably needed from the start was something like groovy -- and yes, my impression is that the ecosystem is becoming more sane.
BTW, java doesn't have multiple inheritance (well, it might have now that you can add some (static)code to interfaces[2]) -- it has (weak) contract based programming (via interfaces).
[1] http://www.amazon.com/Program-Generators-Java-Craig-Cleavela...
[2] http://docs.oracle.com/javase/tutorial/java/IandI/defaultmet...
Jython (then called JPython) came along fairly early, in 1997 and feature complete but never took off for testing or gluing Java code. Jacl, a Java version of Tcl, also came around 1997 but virtually no one used it. Beanshell was built before Groovy, removing static typing but keeping the rest of Java's syntax. Groovy duplicated Beanshell's use case but brought closures and terse collections syntax, but didn't get any significant users until the Grails project spent a year (2006) retrofitting it with a meta-object protocol so it could be used with Grails. A second growth spurt happened in 2009 when Groovy added a DSL syntax to its already klunky grammar so Gradle could use it. Though you could argue Groovy's use in Gradle builds isn't very significant because the build files are typically 20 to 50 lines long, using the DSL syntax only and not making any use of the actual Groovy language features. And Gradle may not use Groovy as a build language for much longer. Calling Groovy an "overhead in the IDE-to-Gradle communication", the recent Gradle 2.0 roadmap [1] says:
"Android Studio demonstrates the enormous potential of a deep integration between the IDE and Gradle. At the moment, the price we pay for this is often mediocre responsiveness: every time the IDE makes a query of Gradle, the configuration phase is run before an answer can be given. The folks at Google are implementing some smart workarounds for this. But what is ultimately needed is a fundamental solution within Gradle that eliminates the overhead in the IDE-to-Gradle communication."
[1] http://forums.gradle.org/gradle/topics/revolutionary_new_gra...
I should perhaps have been a little more clear: I didn't mean to imply there were no scripting languages for java, just that they weren't first-class citizens of the platform (Beanshell being an exception -- but perhaps it too suffered from being a bit heavy?).
It's interesting that Gradle seem to be moving away from Groovy -- especially considering the section on configuration: It appear they're moving towards a functional-flavoured architecture -- and at the same time further specializing Gradle -- so that it'll (probably) be a better build tool -- but also quite useless for other tasks/customization. Or rather; it would appear the project will not be much of a driver in improving Groovy for projects that need some form of dynamic configuration etc.
On the other hand Gradle will (presumably) serve as nice architectural model to follow for other projects (move towards a functional style, rather than programming dependencies in a procedural manner with a hacked up xml dialect).
Perhaps one of the core issues have been projects mixing complex configuration requirements (eg: routing for tomcat) with simple requirements (eg: username/password etc -- stuff that works well in a ini-like format). I suppose that if you've determined you need complex/powerful configuration, you'd be hard-pressed to include a second form of configuration in your project. After all simple xml files are almost as readable and easy to work with as ini-files... And yet, for a lot of projects, it's ended up being a bit of a mess.
I think this pattern was popularised in the Design Patterns book (Gama et al).
But my guess it's a natural progression from a standard Factory; Factories allow instantiation without specifying any type, and FactoryFactories afford the same flexibility, but just for instantiating a Factory without knowing it's type.
This was probably reenforced by the fact that life was easier if you built to interfaces rather than implementations, so factories were good for this.
I actually love the design patterns book, but I sometimes curse it - especially when stumbling upon things like the AbstractSingletonProxyFactoryBean. WTF!
http://docs.spring.io/spring/docs/2.5.x/api/org/springframew...
The new .NET web stack is pretty amazing
Go is pretty great