Never before in my life I had seeing such a great misunderstanding about some sort of thinking, the thinking of design computer software based on intelligent objects, behavior plus state, bound, for better human understanding and maintainability. That's the story of a very good humored rant on Object Oriented paradigm that started gently as just a unimportant, misplaced critic on the Java syntax. (Warning: great amount of sarcasm and irony below)
This unforgivable sin of Java not allowing you write functions without a class as its context (yes, this reading requires some basic OO principles, I'm not sorry) was WAY OVERHATED by the author of Execution in the Kingdom of Nouns (referred from now on simply as the rant
), in such a way that it takes about 1,500 of words (small games could be written with that) to make its critic. To those of eager to know why I was so perplex in front of this, let me give you just a example:
int inc(int i) {
return i + 1;
}
In Python:
def inc(i):
return i + 1
In Ruby:
def inc(i)
return i + 1
end
In the grotesque Java the following nature's mistake would have to be written:
class foo { static int inc(int i) { return i + 1; } }
More verbose, indeed, 2 astonishing lines of overhead, can you imagine? Two lines per source code file!!! Indeed, we cannot bare such errors in science. </br> But let's keep going on with our example, let's for a moment image a Java source code file with about 3 or 4 functions:
class foo { static int inc(int i) { return i + 1; } static String logError(String s) { //code here } static void order(int[] a) { //code here } static double buy(int productId) { //code here } }
With this examples in hand dear reader, you can make your own judgment of who has a case of Xenophobia
.
As you can see, we keep with the unacceptable 2 lines of code overhead. I think I'm done with this part of the rant, which by itself could never call my attention in such a way to the point I loose precious hours of my weekend to give my tiny share of justice to the facts I'll present.
The fact that the Object Oriented design of software is a natural evolution of the procedural way of thinking.
But let's first retain ourselves to the statements in the rant.
because architecture consists entirely of nouns. (fromthe rant)
Architecture in OO software design if not about nouns or data, but it is about behavior, operation, verbs! That's the base of OO, the aspect called polymorphism. Never heard of it? Oks, let's evolve, have you ever used or saw a powerful feature of C called function pointers? Oks, evolve that idea a little more, add to your language a natural syntax for that and you will have the very first bricks to what was named Object Oriented design. But of course, that's only part of the story.
Have you ever heard or used global variables? Oks, have you never wanted them to have a less global scope? have you ever wandered where this variable was declared? In which file? Have you ever imagined why some company had the idea to put the types of each variable in its very own identifier (perhaps because it was too painful to find its declaration...). And finally but not less important, have you ever prefixed a group of variables or functions with the same name? like:
In terms of functions (verbs):logError(String msg); logWarn(String msg); logTrace(String msg);In terms of data (nouns):
String clientName; String clientAge; String clientEmail; double clientDeposit;Perhaps Both?
scheduleVacation(Employee e, int month); String EmployeeName; double EmployeeSalary;
Can't you see this functions and variables are naturally trying to live together? And the great majority of us humans can't make sure the salary of one Employee won't be used to process a client deposit? In real life systems that today easily have hundreds of thousands of lines of code, wouldn't it be better if a compiler of interpreter stop us from mixing all these global variables in our huge data bank of programming code statements?
To bind data and functions, state and behavior, nouns and verbs is what OO calls objects. It can be class based as Java or Prototyped based as Javascript, it does not matter. BTW, the author of the rant puts Javascript as regular procudural language, couldn't this definition be more wrong. In JS every function is a object.
Let the compiler or the interpreter (or mainstream IDEs, more common among statically typed languages) handle the consistency between data and actions. Of course, no software today can prevent you from mixing your data or make a bad design, but I think I just don't need to explain the problems of global variables among thousands of lines of code.
Objects narrows down the scope of global variables to a single instance. I'm not talking about having the scope of a source code file, I'm talking about the scope of a instance, your functions will act only upon a logic gathered set of data (and of course the parameters of your functions [I'll stop with the obvious, I promise...]).
In java you can have:
class foo {
static DatabaseConnectin conn = ...;
static int currentQuarter = ...;
static int inc(int i) {
return i + 1;
}
static String logError(String s) {
//code here
}
static void order(int[] a) {
//code here
}
static double buy(int productId) {
//code here
}
}
The marked lines above are not a C regular global variables, but package global variables, which restricts their scope a lot less than the hole set of files of your application.
But wait! You can also have single file global variables (each time less global huh?):
class foo {
private static DatabaseConnectin conn = ...;
private static int currentQuarter = ...;
... functions here ...
}
The marked lines above makes these variables available only to the functions of one source code file. Reducing drastically the number of implicit dependencies among all other functions in all other files and these variables. Memorize this concept called "Implicit Dependencies", ask yourself why they must be avoided?
Any experienced programmer will know the answer. And certainly OO techniques helps us to avoid them.
setLifePoints(&player, points); moveToRoom(&player, roomId); initNPCs(&room, npcs);
Well, that's just objects Player and Room screaming to have their own voice, their own right to shout verbs, their own functions, to handle their own data.
After all, in the most cases all we care about is the actions of our code to be completed, not how they are performed. Let us create this concept of Objects and let them handle themselves with their data, let us just ask them to take the garbage out for us, close the garage door, enter the house, etc (the rant
references).
Well, Object Oriented languages have just a natural way to express this, this wau is the creation of no one less than the very own hated and feared... Objects!!! (doesn't "hate" have its origins in fear?).
A very different way of thinking software design, in such way different that some people just feel really insecure to dive into. But that's all normal, to loose a paradigm is to loose, for at least a short time, the floor underneath your feet.
class Player { setLifePoints(int points) { ... }; moveToRoom(int roomId) { ... }; moveTo(Room r) { ... }; } class Room { initNPCs(npcs) { ... }; }
It's far beyond the scope of this blog entry to teach the Objected Oriented design techniques, as it's also the teaching of Good OO principles. We must remember, ANY tool can be badly used, never underestimate one man's imagination :)
Dude, not everything is an object. (fromthe rant)
I agree that other paradigms like the Functional one has its safe place under the sun, as OO has also its safe place under real life BIG systems, what I cannot say about the procedural approach, because even being possible, there are better ways like OO. Designing intelligent, behavior targeted objects is not easy as simply design procedures but on the other hand is not like learning Hebrew, not at all.
And let's make something very clear, the Functional paradigm is a world apart from procedural and OO ways of thinking (the rant rightly states that).
I did not want to get back to that syntax huuuge problem of Java, but one final note about it, with java 5 static imports the rant
author can have almost all he wants from java syntax. Badly designed libraries exists in all realms of computer languages, the syntax of how to declare or invoke functions could never be held responsible for that, isn't it obvious?
Getting back to what matters most, the true value of Object Oriented systems comes from Polymorphism, when behavior morphs or change from a type implementation to another, and switch cases are banned from cloning themselves all over the system, along with data boolean expression to take specific actions.
I'll dare to try to give some examples, (even without presenting important mechanisms like inheritance, interfaces, etc):
You could have a Type Employee and two implementations of this type, the Director and the Manager. The type would define common operations like calculateBonus, scheduleVacation and approve(Project). Each type implementation or Class would implement these operations according to what it would be representing, a simple Manager or a mighty Director. You would only have to ask each type instance to calculateBonus, scheduleVacation or approve(someProject) without needing to know the rules specific to each type implementation. No switches every time to check if(employee.type == MANAGER) { ... some project workflow approval ... }, so when a new project workflow approval appears you do not need to chase or grep hundreds of files to add one more case statement.
Well, examples much more decent, elaborated and supported with code are available in the literature since a few decades now. I do not intent to try to teach (which is a art by itself) the little I know about OO here.
Even though I just hope to have helped to undo this huge misunderstanding of such good software modeling technique without whom great projects like Eclipse or the Spring framework could not be done, among hundreds of others even more expressive (give me a break, I can't and don't want to remember much more, it 00:44 am, Friday ;) Ask KDE developers what they think about OO if these java world examples are not appealing.
I strongly recommend the reading of Object-Oriented Modeling and Design. And also a lighter reading on chapter 7 of Objects First with Java.
This is a very passionated post, I know I could be more didactic and clear, but I just want to end this wrinting for this weekend :)


Comments
The lack of first-class functions in Java adds a whole layer of complexity that is simply unnecessary in most other languages.
It's just funny that you did not mention a single language (except LISP, but you were talking about OO) that supports High Order Functions.
And this feature, besides powerful, adds a layer o complexity to which the most part of programmers are not used to handle. Most of all those who are still in love with mechanisms like 'simple functions' that requires much less abstraction than thinking for example in a Object Oriented model, or a Functional Programming model.
So, yes you can write bad APIs in other languages, but Java *IS* a bad API.
Part of Java's problem is that each new class has to be in its own file. So you get "two lines per source code file" *and* one new source code file per procedure! But ok, one could pack his procedures into the same class, making the class a poor substitute for a proper *module*. Unluckily, Java programmers don't program that way.
And about the hibernate stuff and all other things that are made with Java: They suck! (I have used them, I know what I am talking about.) Example: Try to access a NEW table in your database (databases change!) with Hibernate and with the JDBC driver. Hibernate forces you to create at least 3 classes with lots of idiotic code, in JDBC you can just iterate over the new table. (Hibernate loads the whole table into RAM by the way!)
And by the way, I've programmed in C, C++, Java, Delphi, Lua, Python, Euphoria, Eiffel and a bunch of other programming languages and I have to say this:
* Java attracts dumb programmers which think that they write good code if they use many *design patterns* (many design patterns suck). I've yet to see an AbstractWindowFactory in a sane programming language.
* People that only know Java and C/C++ like Java better because of the GC; people that know Eiffel or Python (depending what one needs to do dynamic or static typing is more appropriate), know that Java is an inferior language and even a bad OOP language.
I meant JDBC is (IMO) way easier to deal with than Hibernate. So, I have nothing against JDBC, but I don't like Hibernate. (I know what JDBC is.)
"Funny, design patterns are not tied to any programming language, even among the plethora of languages you know."
You are right, design patterns are not tied to any programming language, but most patterns only deal with how to avoid many of the problems that OOP causes. But I have seen more usage in desing pattern in Java code than in other code. A programming language has a *community* associated with it these days. It is the Java community that is incompetent (IMHO).
"By the way, which successful GUI toolkits you said you have designed?"
To be honest I would love to design one that is not based on OOP, but on a data-driven paradigm. I don't have the time. However, I have used Delphi's VCL and Java's Swing and the VCL is superior in almost every way. An example: In Swing you use LayoutManagers to place the widgets (and you need to nest them in various ways), in the VCL you just give the widgets *anchors*.
"My dear reader, you have never used Hibernate." Yes, I have. JDBC was much better.
Java's flaws as an OOP language:
- Lots of code out there that does not use the new generics because they were added too late. The implemenation of generics also sucks: This is widely known. Google a bit to see.
- The special object creation syntax (new Object()) leads to factory pattern that is only needed, because of the special "new" syntax.
- Lack of abstraction for the == operator concerning strings, again Google is your friend.
- Lots of getters and setters are needed because Java lacks properties.
- Inheritance is a language feature and delegation is not, even though OOP gurus agree that delegation is more often needed than inheritance (the other programming languages have the same problem).
- etc.
Yes, you *do not need* the features I listed here (Java is Turing-complete). But they make programming easier, they lead to fewer code or automate more tasks, which is programming all about. Look at Eiffel if you don't believe me.
And finally:
"I'll not again show the benefits of OO against modules oriented programming."
You showed nothing. Structuring the data by using records was done in 1970 without OOP. But I will stop now, I have to read the book "Abstract State Machines", which was written by *smart* people. By the way this is what the cover says:
"In several industrial projects the ASM method has proven its superiority compared to the popular UML mehodology when designing complex parallel or dynamic systems."
You haven't identified yourself but here goes your reply. Why to hide? Sure, JDBC is easier to master than Hibernate, the same way one simple tool is easier to handle than another complex one, the same way procedural code is easier to write than OO code. But with the complexity of OO you can achieve more sophisticated, flexible and maintainable code. The same way a surgeon cannot use a band-aids to finish a surgery. That can only be FUN. Practical examples please. I see, we should use the amount of code you saw in your life to make scientific research. I mean, a anonymous statement like that worth much more than nothing. We from the Java community should bend to your words, anonymous reader. STOP! a GUI toolkit not based on OO I've seeing already, take Gtk, but one based on a data-driven paradigm?!? Are you talking about a user interface API based on database tables??? Oh yes, that's the sole reason you don't build you GUI toolkit that needs a database. Interesting indeed to hear this about Delphi's API. If better means simpler and if it's ok to you to make a big corporative building just with some bricks and hammers. 1st: All the java SDK uses Generics since it was provided by the language.
2nd: By your logic one language should be born with its features and never add anyone more? Otherwise there will be always statements like this: code out there that does not use the new $ANY_FEATURE because they were added too late to all programming languages. Google a bit about Python to see one good example of a language that is always getting more features.
How does your language of choice creates objects? Btw,
newcan be seen is just as a memory allocator operator. I know pretty well the Immutability of Strings (which is a feature) in Java and when to use the == or the equals method. Be more clear about your critic above the == on strings. Better saying, a property in Java, according to the Java Beans spec, is defined by getters and setters. Which language has a delegation mechanism? Better saying, inheritance leads to a more coupled code than Composition of Aggregation. But I assume you've heard of Coupling in software models and why high levels of if must be avoided. Ufs.. such a relief... They WHAT? stand alone functions do it all??? So why OO was invented? These crazy academics, industry gurus, software developers... cheating us all for so many decades... Teaching OO is beyond the scope of one blog post. It's not like just typing some functions. You are 100% right! The same way database Records are pretty far from being Objects! I always believe in book covers. Good reading ;-)First, Java IS NOT a API, but I bet you know that.
Second, Java HAS NOT a bad API, but I'll not give myself the work to show you that. But I, on the other side, am indeed inclined to leave you an invitation, an wide open door for further discussion on that matter, perhaps provided with some arguments, so then I'll be able to analyse them.
http://www.sics.se/~joe/bluetail/vol1/v1
http://www.geocities.com/tablizer/oopbad.h
And look especially at the examples given in the last link. Yes, I know he compares OOP to communism, which is a bit extreme, but inspite of this there are *good arguments* on the page.
module SomeFuncs {
void foo() {}
void bar() {}
}
The language Nemerle http://www.nemerle.org does does something like that. C# has static classes which enforces that everything is static, but insists that everything still be declared static for some bizarre reason. Well, I know the reason, but I just don't agree with it. In Nice (http://nice.sourceforge.net), there are package level globals.
Oh, and I reject your notion that OO is a natural evolution of procedural.
If you use the static keyword in all your method declarations plus with the static import feature introduced in Java 5.0 (as I said before) your class will act just like a module and it's clients will fell like using regular functions."
Two problems - one is that you can still have instance methods and data. Java doesn't enforce it. Second is that I think it's wrong not to have a keyword like module to say these are package level functions and data. It's not a class (in the Java sense).
" Oh, and I reject your notion that OO is a natural evolution of procedural.
I'd love to hear your reasons as you've read mine :-)"
It should have said ...natural evolution of procedural thinking". I forgot the thinking part. I do think that OO is an evolution of procedural, I just don't think it's a natural evolution of "thinking". My reason? I just don't think it's particularly intuitive, especially in the mixed-data-and-methods sense.
Someone else linked this, but I'll link it again because I think there are some valid reasons there. http://www.sics.se/~joe/bluetail/vol1/v1
I'd rather do OO in the Dylan/Lisp CLOS sense of OO instead of the Java sense of OO. Hell, I don't even find Java to be a particularly good OO language.
I would like to know from the anonymous reader what are the advantages in adding such a new keyword called module at the Java platform. What Java lacks from not having this keyword? Suppose your company is focused in building monetary systems and you have a requirement to create a reusable component who realizes conversions between currencies. What's the difference in creating a JAR file with a bunch of utility classes who only have static methods acting as procedural functions (that is, receiving input and producing formatted and converted output) and defining a new module keyword? Java needs classes to define static methods because OO programs are programs
described by classes. So, I wanna know if the effort in adding such a keyword would be worth than not applying the proper Java features to build a reusable module. Couldn't you have the same behavior without introducing the module keyword?
I'd say it's a natural evolution of software modeling, and I agree that it's not intuitive.
"Intuitive thinking" leads to procedural code, while software engineering leads to OO.
That, I think, it's the main point in this discussion: "intuitive thinking" works great for small, throwaway apps, and the OO "thinking" (modeling) overhead will not be worth it. However, it's completely unfit for team work (because each person's intuition differs from the rest of the team), "big" apps, and for proper software engineering in general.
The larger the application size/team size/application lifecycle is, the better the cost/benefit of OO will be.
Verbs are challenged in a few more aspects in Java. And the primary ones: you cannot have pointer to function and you cannot easily create anonimous functions inline. Only feasible way to emulate is to create a public interface.
This makes something like Ruby code below a bit harder to maintain in Java:
closest_npc = npcs.min do |a, b|
a.distance <=> b.distance
end
Here anonimous class would fit (although will take more space). But if you need something else (not Comparable), you need to go with public interface. If you need to implement listener, it also brings you to interface implementation, full-fledged class or anonymous class.
Sometimes this all really makes code less readable and adoption of useful patterns more painful.
On the other side, the static aspect of Java make extremely powerful tools like Eclipse and IntelliJ IDEA possible :)
I could not disagree more!
The adoption of good modeling decisions could never be stopped by the Java syntax, that's really such a exaggeration. There are hundreds of state of the art OO models implemented in Java nowadays, again: Eclipse and Spring framework are such a good examples. Have you read some Smalltalk code1? That's a very different syntax and at the same time the cradle of so much Object Oriented modeling designs.
And I'm really sorry about the delay to answer you, hard days at work I had in the past weeks :)
1Main Differences between Java and Smalltalk
You have missed the point through lack of experience.
"All" of us know the stuff you write. It's a straw man you are putting up.
The problem, very simply, is that working with various forms of functions and methods have been made very hard by Java. In Ruby, I can pass along an anonymous method like this:
object.methodcall do |arg1, arg2|
... closure/temp-method logic goes here ...
... (called a block in Ruby) ...
end
In Java, I have to build a new class, instantiate an object, initialize the variables for it, use it, and pass/copy the variables out again.
This increase the amount of work by a factor over 10. When you have a factor over 10 difference in scope, you have a DIFFERENT problem. This is true for just about any problem, and thus for any generic solution.
This also means that there are a ton of places where the Ruby block above is extremely helpful where the Java construct is useless, and will be replaced with something else. These cases could be helped by Steve's suggestion of a more compact syntax for doing things.
Eivind Eklund
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
exitApplication();
}
});
4 lines in Ruby, 5 in Java, but in java you have all the help you can have from free IDEs like eclipse to take advantage of the static information Java offers. It's possible to make powerful queries and refactorings on your code.
By the way, with the most simple Eclipse template you can make the IDE write all the code above just typing one word like
winadaptand Eclipse would type all the tedious code and leave the cursor at the statement marked in green. Not that this can not be done in other tools, but my point is that in Java this can be so easy to write...4 lines against 5... and in Java you have the advantages of a statically language can offer with a powerful IDE as I said above. Building *REAL* systems it's really great to:
- know where are all the implementors of this operation;
- know where are all the usages of this class/operation;
- Rename methods;
- I could go on and on...
Without type information in compile-time you have just 'text', not a full decorated AST. Do we "all" know what am I talking about? I bet you know pretty well how better is for a tool that manipulates source code is to have a AST against... plain.rbtext.Please, with "all" your experience, show me something other than {useless, something else, doing things}.
But checking the type statically make the language less compact.
One can see this clearly when one uses something like Ruby.
Modules is a great feature one should see to appreciate this fact.
To this add a decent feature of Functors as blocks.
Then the OO spirit remains, but most of the verbose code is eliminated.
Of course, dynamic type checking introduces bugs.But then sometimes programmer should know what he is writing.
Bruno,
Great post, and very precise too....
I'm only disappointed that u kept on replying to Mr. Anonymous's meaningless ranting.
His arguments draws parallel with the prepostorous theory of Creationism pushed by the Christian right.
They argue with evolutionists with an ounce of rationale and logic to start off with, but they don't go too far. When they are posed difficult question they whimper "its because 'GOD INTENDED THAT WAY' ". And with that they flush all credibility of creationism as science down the loo. Do evolutionists argue that the earth is round because the earth intended to be that way or some similar crap??
U might wonder what I'm hitting at.
Mr. coward's remark 'that all java programmers are dumb' and similar ranting draws parallel with the creationism croonies arguments, they both are baseless hollow statements. When u run out of 2 cents worth of logic and reasoning u say shit like 'God intended it that way' and end of argument or 'all java programmers are dumb and blah-ri-blah'.
Softwares are driven by logic and it requires a brain capable of making logical deductions to write something that runs on logic, so I wonder what kind of software Mr. Coward writes because he totally seem to lack logic and reasoning.....
I haven;t programmed in shitload of languages. But I have done enough programming in PHP and java to appreciate Java as a language and its elegence.
I hate nothing more than maintaining PHP code written in all its functional glory written by someone who's had his head stuck in procedural programming sand. Nothing pisses me more than having to use Tools to do text search to figure out from which file a particular function comes from or where a global comes from. The bigger the project the bigger the headache..
And it takes a lot to refactor the code and organise functions into classes. But its damn friggin worth it.....And I learned the art of refactoring through Java and with it I can make gawd-awful php code shit-load more maintainable. I'm talking about real applicaitons not some blogs or some trivial shits that can be conjured with few lines of procedural code.
I like PHP's simplicity, and I love Java's elegence and managebility.
And I have no problem with PHP, only how people use it to write gawd-awful applications that's a sinkhole of time and effort when it comes to maintenance.
Just because someone jumbles a bunch of words don't mean that it will come out making sense, a rant is a rant even if someone tries to hide it under some literary analogies........