I want to ask – I am slowly learning jQuery.
What I see is an exact example of a God Object anti-pattern. Basically, everything goes to the
$ function, whatever it is.
Am I right and is jQuery really an example of this anti-pattern?
To answer that question, I'm going to ask you a rhetorical question about another structure that have similar property to the DOM elements that jQuery manipulates, that is the good old iterator. The question is:
How many operation do you need on a simple iterator?
The question can be answered easily by looking at any Iterator API in a given language. You need 3 methods:
That's all you need. If you can perform those 3 operations, you can go trough any sequence of elements.
But that is not only what you usually want to do with a sequence of elements, is it? You usually have a much higher level goal to achieve. You may want to do something with every element, you may want to filter them according to some condition, or one of several other methods. See the IEnumerable interface in the LINQ library in .NET for more examples.
Do you see how many there are? And that is just a subset of all the methods they could have put on the IEnumerable interface, because you usually combine them to achieve even higher goals.
But here is the twist. Those methods are not on the IEnumerable interface. They are simple utility methods that actually take a IEnumerable as input and do something with it. So while in the C# language it feels like there are a bajillion methods on the IEnumerable interface, IEnumerable is not a god object.
Now back to jQuery. Lets ask that question again, this time with a DOM element.
How many operation do you need on a DOM element?
Again the answer is pretty straightforward. All the methods you need are methods to read/modify the attributes and the child elements. That's about it. Everything thing else is only a combination of those basic operations.
But how much higher level stuff would you want to do with a DOM elements? Well, same as an Iterator: a bajillion different things. And that's where jQuery comes in. jQuery, in essence provide two things:
If you take out the sugared form, you realise that jQuery could easily have been written as a bunch of functions that select/modify DOM elements. For example:
...could have been written as:
Semantically it's the exact same thing. However the first form has the big advantage that the order left-to-right of the statements follow the order the operations will be executed. The second start in the middle, which makes for very hard to read code if you combine lots of operations together.
So what does it all mean? That jQuery (like LINQ) is not the God object anti-pattern. It's instead a case of a very respected pattern called the Decorator.
But then again, what about the override of
The main jQuery function (e.g.
These instances of the jQuery type have a large number of DOM manipulation methods available which operate on the DOM elements represented by the instance. While this could conceivably be considered a class that's grown too large, it doesn't really fit the God Object pattern.
Finally, as Michael Borgwardt mentions, there are also a large number of utility functions that use $ as a namespace and are only tangentially related to the DOM collection jQuery objects.
Would you call java.lang a god object because of the many classes it contains? It's absolutely valid syntax to call
An object, in order to be a god object, has to be a proper object in the first place - containing both data and the intelligence to act upon the data. jQuery only contains the methods.
Another way to look at it: a good measure for how much of a god object an object is is cohesion - lower cohesion means more of a god object. Cohesion says ow much of the data is used by how many of the methods. Since there's no data in jQuery, you do the math - all methods use all the data, so jQuery is highly cohesive, thus not being a god object.
Benjamin asked me to clarify my position, so I edited my previous post and added further thoughts.
Bob Martin is the author of a great book titled as Clean Code. In that book there is a chapter (Chapter 6.) called Objects and Data structures, which he discusses the most important differences between objects and data structures and claims that we have to choose between them, because mixing them is a very bad idea.
I think DOM is an example of these object and data structure hybrids. For example by DOM we write codes like this:
DOM should be clearly a data structure instead of a hybrid.
The jQuery framework is a bunch of procedures, which can select and modify a collection of DOM nodes and do many other things. As Laurent pointed out in his post, jQuery is something like this under the hood:
The developers of jQuery merged all of these procedures into a single class, which is responsible for all of the features listed above. So it clearly violates the Single Responsibility Principle and so it is a god object. The only thing because it does not break anything, because it is a single standalone class which works on a single data structure (the collection of DOM nodes). If we would add jQuery subclasses or another data structure the project would collapse very fast. So I don't think we can talk about oo by jQuery it's rather procedural than oo despite the fact that it defines a class.
What Laurent claims is a complete nonsense:
The Decorator pattern is about adding new functionality by keeping the interface and not modifying existing classes. For example:
You can define 2 classes which implements the same interface, but with a completely different implementation:
If you have methods which use the common interface only, then you can define one or more Decorator instead of copy-pasting the same code between A and B. You can use these decorators even in a nested structure.
So you can substitute the original instances with the decorator instances in higher abstraction level code.
The conclusion that jQuery is not a Decorator of anything, because it does not implements the same interface as Array, NodeList or any other DOM object. It implements it's own interface. The modules are not used as Decorators as well, they simply override the original prototype. So the Decorator pattern is not used in the whole jQuery lib. The jQuery class is simply a huge adapter which let us use the same API by many different browsers. From oo perspective it is a complete mess, but that does not really matter, it works well, and we use it.