Guiding The Geek In You
A few nights ago over coffee at the local Starbucks I enjoyed one of those moments we as web developers secretly love: a full throttle conversation about ideal, multi-tiered web applications. As we broke down tiers and discussed their relationships, we considered different scenarios: what if the user is on a mobile device? What if their connection speed sucks? What if the site they are using has a million controls?
In fact, what if the website looked and needed to behave like a regular application? Would a massive collection of ad hoc jQuery event handlers, Ajax calls / RESTful services and finely crafted HTML be enough? Maybe. But a better solution exists. Enter the framework.
A framework is a specialized type of library. For programming languages, a library is a collection of behaviors (think: functionality) written in terms of the language, that can be called by using a well-defined interface. Libraries are meant to be used by multiple programs or in multiple areas of a single program, largely because they encapsulate commonly used functionality set apart from the program’s actual code. This makes writing complicated code somewhat easier, as repetitive / complex chores have already been solved and are only a friendly method call away.
A library is passive. Developers must write their code using that library’s interface to get anything out of it. Thus an entire program can be written never using a library’s treasure trove of functionality, even if available the whole time. Not so with frameworks.
Like the libraries from whence they came (poetically anyway), frameworks are a collection of functionality written in terms of the language they support. Frameworks are portable, meaning they too can be reused in multiple projects written in their given language. However, unlike a library, frameworks are bossy. Using a framework correctly means subscribing to how the framework developers view application organization and development. Let that sink in for a moment. Within a framework, your program no longer directs traffic. The framework becomes the traffic cop, and your program the exotic sports car (or three row SUV, which ever you prefer).
Frameworks share four attributes that set them apart from libraries. Where libraries are accessed as needed, frameworks work on the Hollywood Principle, aka “Don’t call us, we’ll call you.” The framework takes care of business and calls your program when it’s show time. The fancy term for this behavior is inversion of control. Second, a framework must have a default behavior, meaning once installed and properly configured, it has to do something useful right out of the box (typically a “hello world”). Next, they must afford some way for developers to extend their functionality, either by overriding default behavior or by creating new behavior within the internal guidelines. Finally, framework internals are considered off-limits. Extend all you want, look under the hood, show it off to your friends, but don’t touch anything inside. Modify the magic and you void the warranty.
During my research I looked at many languages. Each of these languages had at least one framework written for them. So, while a statement like “all languages have frameworks” would probably get me in trouble, I think it is safe to say frameworks have benefits that are tough to ignore, no matter the language. Here are a few popular languages and their corresponding web frameworks:
PHP: CodeIgniter, Zend
Ruby: Padrino, Rails, Sinatra
Java: Grails, Play
Python: Django, Zope2
Node.js: Express, geddy, Meteor
In fact, frameworks are so helpful they are even used in CSS. Examples include:
Frameworks are not for everybody. Some are better than others in any given situation. Frameworks can have tough learning curves, particularly for the novice developer. The unusual usage demands and seemingly arbitrary control flow may seem senseless until well understood. Framework use can also lead to code bloat by adding unnecessary functionality and inspiring work arounds written by developers unfamiliar with the framework’s complexity. Speaking of complexity, take a look under the covers and marvel at the magic. Pre-implementation study and research is sincerely recommended!
These are real concerns you should absolutely consider. However, frameworks also bring a feast to the table. As well-tested and typically open source application scaffolding, frameworks can help separate concerns in extremely reliable ways, decreasing code spaghetti. In fact code quality is often amplified when developers follow usage rules and color inside the lines. Although structured, frameworks are extensible when necessary – while still cutting development time by taking care of common tasks (just like any other library). Finally, over the long-term the framework becomes invisible, improving project delivery time and code reusability.
Thanks for reading, and happy frameworking!
Invented by Trygve Reenskaug, who originally called it the “Thing-Model-View-Editor” way back in 1979 (read all about it), the MVC design pattern has been a staple in software design since it appeared in the Smalltalk-80 class library.
Discussing software design patterns exceeds this post by light years, as does the interior magic of MVC (and siblings such as MVP, and MVVM, and so on). However, let’s cover a couple quick concepts in as non-boring-as-hell way as possible.
The MVC design pattern is focuses on “separation of concerns”. Meaning, software built using this design pattern is composed of pieces belonging to one of three main areas:
For example, when the user interacts with the software by changing the contents of the first name field, the controller handles the user input and changes the state of the model (which is responsible for storing that name somewhere). The controller does not directly tell the view “hey, the user changed the first name and I asked the model to save the information.” Instead the view is observing changes made to the model, and when those changes require a refresh of what the user actually observes on-screen – that refresh happens.
This is simplifying a more in-depth process – but hopefully you can appreciate how each piece has a unique role to play, and that the unity of these roles forms a very tight and reliable pattern for software design.
Understand: when you use a framework your code rests upon and within it. There are rules that should be followed, and coloring outside the lines is discouraged – and can sometimes be disastrous. So choose your coloring book with care.
A quality code base and an appropriate feature list. Will the framework do what you need it to do? Do you understand what’s happening under the hood?
Has the framework been endorsed by big companies? Implementation is a great sign of endorsement – do your research, who’s using this framework?
Are other developers actively supporting the framework? How many? Are the builds coming out fast and furious? Stability is good, commitment to growth over time is even better.
Documentation is vital! A big advantage to a JS MVC framework like Backbone is the sheer number of educational resources available to the developer.
Frameworks exist on an “opinionated” scale. Some, like AngularJS and Ember.js, are tremendously opinionated and will, via convention and scaffolding, handle many basic duties on behalf of the developer. These duties can include standardized file and URL structures. Un-opinionated frameworks like Backbone leave file and URL structuring up to the developer, sometimes frameworks even ask the developer to figure out their own routing and data storage solutions.
How interoperable is this framework? If you want to gently insert pieces of a framework into your existing code base, will the framework tolerate it? Backbone is happily inserted where ever you squeeze it. AngularJS is also friendly, but prefers some control – for example AngularJS prefers (but in no way requires) its built-in jqLite over jQuery, mostly because jqLite makes unit testing easier. Ember.js, however, demands total domination. It wants to control the entire page at run time.
Consider your target audience and the devices they likely use. Now, look at the file size of your framework including all dependencies. Realize that fully featured frameworks like Ember.js come equipped with built in solutions and typically only requires a single dependency, handlebars.js. Backbone, on the other hand, despite how lightweight and un-opinionated it is, needs underscore.js and jQuery (for desktops) and / or zepto.js (for mobile) to run. These requirements add weight.
Finally, avoid the insanity caused by YAFS (Yet Another Framework Syndrome) by downloading and using the amazing TodoMVC. TodoMVC is a collection of many of the leading JS MVC frameworks and assigns a single task to each: render a handy little To-Do List application. The UI is friendly and identical between each implementation. All of the code is exposed and ready for analysis. WooHoo!
Consider the problems solved by a framework:
Now consider the pain a framework implementation will bring:
Lastly, keep in mind that implementing single page applications is the core strength of the JS MVC. Therefore, if your project is a basic web page application a framework might be an over-engineered solution. I say “might” because some frameworks, like Backbone, can usefully solve common issues even in these traditional applications.
Awesome! Go download the framework and the dependencies, then load them into your Hello World project template, just like you would a JS library. Or, if you prefer and the option is available, use the CDN made available by the framework community.
After the World has been Hello’ed adequately, study the TodoMVC implementation of your framework. Peel back the covers, read the comments, study the hell out of the source and do your best to understand what is going on. You may come to rely on the awesome magic Ember.js, AngularJS, or your MVC of choice provides – but first do your best to understand it!
Finally, start your own project. In upcoming posts I will be discussing my project, including which framework I use and why. Stay tuned, and thanks for reading!