Historically I have not been a fan of “frameworks”, and I have often repeated the following joke:
What’s the difference between an application and a framework?
An application is something a customer actually wants!
However, for some applications, I recommend use of an application framework. For some Oasis Digital projects, I require it:
Please, Use a Web Application Framework
My reasoning here applies specifically to web applications with many CRUD (create-read-update-delete) features, and an underlying database. The advice applies much more widely, and with many nuances and caveats, but this article I am discussing only CRUD-ish web applications. Even within this niche, my reasoning does not apply to web applications which “push the envelope” of what is possible or which attempt to advance the state of the art.
Regardless of the programming language, the application should be built on a framework. More specifically, the framework should popular and mainstream, with a community of developers, and the appearance of momentum for the future. Likewise, the client-side JavaScript used in these applications, should also be based on such a framework. Here are some examples:
Ruby: Ruby on Rails, IOWA
Python: Django, TurboGears, Pylons, TwistedWeb
PHP: Akelos, CakePHP, CodeIgnitor, Symfony, Zend
Java: Struts, Seam, Rife, Tapestry, Stripes, Wicket Spring MVC
JavaScript: Scriptaculous, Prototype, JQuery
This is just a list of some frameworks that I am aware of; I have not evaluated all of these in detail, and I do not endorse them; nor is this an exhaustive list. For Oasis Digital projects, we help evaluate proposed frameworks, then I personally give the go-ahead to use a particular framework for a particular project.
An in-house web application framework does not meet the “community of developers” criteria, except at the very largest firms. Everywhere else, you are better off with an off-the-shelf, popular framework than with an inhouse framework, even if the latter is brilliantly designed.
Justification
My recommendation (and requirement, for some projects) for using an application framework for this kind of application is not based on a fad. Rather it is based on my years of experience as a developer, a team leader, a maintainer, and most importantly, a customer of software development.
The wild success of some frameworks (such as Ruby on Rails) has shown that they can reduce the amount of code and time needed to develop an application. That second factor, the amount of code specific to the application, is at least as important as the development time. Lines of code are not an asset; they are a liability. Only the features that the code provides are an asset. The most valuable software provides a lot of features using the smallest possible amount of application-specific code.
Therefore, even if a developer is so extraordinarily fast that they can create a system very quickly without using an off-the-shelf framework, they still have provided less value by doing so, compared to creating that same system quickly with fewer lines of code.
Another benefit of using a common framework (not a custom, in-house framework) is that this makes an application much easier and faster for other developers are work on in the future. A more maintainable system is more valuable.
Framework Caveats
Vidar Hokstad left a lengthy and excellent comment below, disagreeing with my thesis. It turns out that I mostly agree with Vidar, and it sounds like he and I have been through many of the same experiences with poor application frameworks. There are a lot of things an application framework can do wrong, and sadly, many of them take the opportunity to do so. In-house frameworks created by “architecture astronauts” seems to be especially prone to these defects:
- All-or-nothing: Some frameworks intentionally or accidentally make it hard to replace a section of the framework. Don’t use these. Use a framework instead that has a “library” philosophy, such that you are readily choose to use some parts but not others.
- Just Different: There are frameworks which offer an API wrapper around the underlying mechanisms, which isn’t really any better, just different. In this case, different is worse. Writing to (for example) the com.acme.inhouse.servlet API is, all else equal, much worse than writing to the standard Java Servlet API. To be worth its weight, a framework API must be demonstrably and obviously more concise.
- Lower Abstraction: There are frameworks which, ironically, lower the level of abstraction of the application code, because that code ends up working around the framework features to get the job done.
- Pile of Pieces: There are frameworks in which it is necessary to shred your application in to a pile of pieces, and then wire those pieces together with configuration files. This is sometimes useful, but often makes the application harder to understand, not easier, especially if there are extensive “XML pushups” involved. (I’m looking at YOU, Struts!) Instead, choose a framework with convention-over-configuration, and one which offers but does not require manual wiring.
- Keyhole Database Access: If you find you mostly use a frameworks’ DB access features, and as a result you have short, easy to change code, then keep it. But if you find you use extensive SQL to work around lots of framework issues, throw it out. If a framework intentionally makes it hard to reach to the underlying SQL access, throw it out now.
- No Source: If someone proposes a framework for which you won’t have source code, laugh. Aloud. If this gets you fired, then it has set you on a path to find employment at a more enlightened organization.
- Exceptionally Bad Exception Handling: Java frameworks are especially prone to issues with exception handling, in which the framework code “eats” exception details.
In summary, pick up a framework and use it to get your application up and running quickly, but don’t be stupid. Do what makes sense locally for your project over time. It is a win to use an application framework to reach “1.0” functionality, even if you end up removing or swapping out parts of it later.
I really couldn’t agree less with you when it comes to arguing for frameworks.
The reason I avoid frameworks like the plague, is that whenever someone feel a need to call something a “framework”, it almost automatically follows that they’ve introduced far more coupling than needed. More coupling means less flexibility in replacing components that don’t fit your application, and inevitably leads to people writing a lot of code to work around limitations they wouldn’t have in the first place if they had the freedom to pick the best component for each part of the job. I’ve yet to see a framework for which this doesn’t hold true (I would not have a problem with a framework that was truly just a collection of independent, easily replaceable components)
A typical example in the Rails stack, for example, is the amount of effort people have been putting in to work around scaling issues with ActiveRecord (far more database calls than needed, and lack of proper connection pooling and support for partitioning etc.) rather than just yanking it out and using something more suitable for their apps.
I agree with you that lines of code is a liability, and that is _exactly_ why I disagree with you on frameworks. I’ve yet to come across a single time when using a framework over judiciously combining independent, highly cohesive components into a loosely coupled system would have resulted in less code for me, because picking components lets me get a much better match than trying a one size fits all solution.
It’s not time that’s the issue. In fact, the process of picking the right tools often by itself makes a framework-less process longer than just jumping in with a framework that may or may not fit your needs. It’s more time consuming because you have to make a conscious choice about WHY you’re picking a specific ORM, or a specific template engine, etc. At the same time, each choice is less costly in the long run than picking a framework, because the cost of rewriting the app to replace a component is far lower than the cost of replacing the framework or working around problems in a single component when those problems get severe enough that replacing the component would have been the preferred choice.
I also wildly disagree that using a framework makes the application much easier to understand. On the contrary, frameworks tends to obscure a lot of control flow that I really don’t want obscured. It means that once whichever framework you pick is not the hot new thing anymore, you are going to find that getting developers that happens to know just that framework well becomes increasingly hard, and that’s exactly when you don’t want your application to depend on huge masses of code you can’t quickly and easily get up to speed on.
@Vidar
I’ve seen the results of blindly rejecting using any framework many times in my career. Very often, it leads to in-house developed frameworks of inferior quality. Bad quality because developers didn’t think their abstractions through well enough (they didn’t need a framework, just a couple of quick hacks), because they run into the same issues framework developers ran into, but without a community of thousands of users that help with testing, propose issues and fixes, etc, etc.
Blindly rejecting frameworks is as short-sighted as blindly accepting any of them. It is important that you select the right one. Certainly, using a bad framework is worse than not using any at all, and sometimes not using a framework is a good choice, as long as you don’t make it a dogma.
Having used Catalyst (Perl) and jQuery quite a bit, I see several major benefits from frameworks: minimizing the “not invented here” approach to web applications means new contributors are more likely to have more experience of the scaffolding and meta-language that holds your web app together. This saves a lot of resource.
Like most new tricks in programming, we all are at danger of over-using it when we first get to grips with it, and start looking for framework plugins to do things that the framework wasn’t designed for. But once we settle in and learn that the core of the framework is where the big wins lie, and to avoid over-dependency on its peripheries, a lot of the drudge can be eliminated from a project.