Some time ago, my colleagues and I had a discussion about the usefulness of JavaScript frameworks given the current state of web browsers and their support for modern HTML5 standards.
The first article that sparkled that debate was The deepest reason why modern JavaScript frameworks exist, by Alberto Gimeno. In his article, he claims that JavaScript frameworks are needed to synchronize the user interface state and the visual components of the user interface.
I thought that this argument didn't stand anymore, because web components would meet that demand with support for bindings or something similar. Unfortunately, I was wrong: web components can do many things, but synchronizing state and UI is not one of them.
The second article was Do we still need JavaScript frameworks?, by Luke Joliat. In it, he develops a simple application using vanilla JavaScript only. He demonstrates that you actually can refrain from using frameworks up to some "tipping point". That point would be the application' size/complexity: there is a time when, no matter how much you try, the need for code reuse forces you to use a framework. Either you use an existing framework, or you end writing your own homemade framework, focused on solving your specific problem (which is not necessarily bad, as that's how many successful frameworks came to be).
It's here that both articles kinda agree (I and agree with them): whenever you go beyond trivial, you need some structure that helps to abstract the solution that you are creating for the problem you're solving. Programming languages by themselves give some structure, but that's not enough. It's been quite some years that programming languages don't come bundled with heavier frameworks that allow for more complex applications to be developed. I believe that's deliberate: even though there are patterns that can be found in many frameworks from many languages, the users of these languages like the freedom to tinker with different abstractions.
That is different from "older fashioned" technologies like Visual Basic, Delphi, JSP, and Classic ASP. All of them have in common the provision of a native framework that can be used for structuring applications. Coincidence or not, the frameworks all these technologies offer are based on two pillars: components and event-oriented programming – essentially the same features that the most famous JavaScript frameworks provide. The main difference is that in older technologies there was no separation between state and UI: the UI IS the state. It's like keeping all information about the user interface' state in the DOM, using only classes, attributes, and properties. Anyone that has already used these older technologies to build complex user interfaces knows that this way of doing things has a limit, and soon you're creating all sorts of flags and ancillary variables trying to put some order to this big mess.
The important innovation of the last years is explicitly separating these two concepts: the user interface's logic state, which is (somewhat) independent of the way it's presented and the specific components you use; and the user interface itself (eg: the components or HTML tags). When you split these two concepts you create (or expose?) the need for state-UI synchronization, because the user interface has its own internal state (controlled, for example, by the operating system or the web browser).
This separation is not new. It exists since at least the 1980s when the MVC pattern was adopted by Smalltalk. The novelty is that separation becoming mainstream (which is something good). Having the user interface logic isolated in a class without concrete UI dependencies makes testing easier (especially unit tests) and forces the developer to think about the user interface more abstractly.
For me, the definition of "framework", what differentiates it from a "library", is inversion of control (IoC). Instead of your code calling some external code, it's the external code that calls your code. The base of the application' structure is not your own code, but the code of the framework. You're given extension points and slots where you put your code, and the framework calls your classes and functions as the user interacts with your application. That allows us to "shift up a gear", to abstract more of the implementation because it hides questions that permeate the application as a whole: access control, sessions, database connections, logging, debugging, profiling, templates and user interface rendering, uploads, forms, validation, etc.
As someone that has used many frameworks, has created more than one framework and has tried to develop without frameworks, I can say that frameworks are really necessary. My experience building "small customer registries" that in time turned to be "little monsters" is exactly that: code reuse through functions and classes, then libraries with more abstract components, then finally inversion of control – in other words, a framework. Even when I tried to get develop with no framework, I ended building a micro-framework because the programming language by itself didn't provide the abstraction level I needed.
There's a saying in some not-so-mainstream programming languages circles stating that "design patterns (eg: Facade, Singleton, Observer) are only required when the language is not rich enough to describe these behaviors natively". I never found a language, be it object-oriented, functional, logic, concatenative or of any other kind, that allowed one to dismiss each and every pattern.
Maybe it's impossible to create a programming language that natively offers all features needed to discard design patterns and frameworks. Or maybe that's the next step: a language that offers, natively, inversion of control. I'm not sure how that would work (maybe something similar to AOP - aspect-oriented programming), but I think it's something to consider: the language would be indistinguishable from the framework.
What do you think?
Top comments (0)