Why I Hate Frameworks
discuss.joelonsoftware.com
discuss.joelonsoftware.com
A good framework is nothing more than your toolbox
filled with a good selection of tools. Some tools are
very general purpose (standard claw hammer) while others
are very specialized (roofing hammer). Having them all
available and knowing when to use them is half the battle.
No, sir. That is a good library.Most frameworks are composed of libraries anyway.
There are frameworks specifically designed to be modular, and of which 90% can be used as a library, without being forced to apply it's MVC or scaffolding bits.
The line between framework an library is a blurry one in a world where "framework" does not equal "Rails".
Library: you call it.
A library is something *contained* within my code.
A framework is a *container* for my application."I've done small woodworking projects before, and I think I have a pretty good idea of what I need: some wood and a few basic tools: a tape measure, a saw, a level, and a hammer."
The reason I hate frameworks (even things like Django which is very easy to get started with) is that, at some point, I'm asked to re-learn a different way of solving a problem that I've already solved in the past.
I've been doing lots of thinking about this having written the Great American PHP Framework myself, and worked with other people's frameworks, and also worked a lot in the CMS space and the biggest conclusion that I've come to is that the best tools are those that enable you to do things faster or more conveniently but don't actually provide any abstraction.
For example, when deploying a website there are any number of tools to "abstract away" the HTML layer - templating engines, markups, markdowns etc. etc. but the best way to build HTML is using HTML and testing in a web browser, always.
When you need to write some code in whatever web framework you're using to handle a POST request, you want to be as close as possible to the HTTP layer without a bunch of arcane systems in between you and what you and the underlying technology.
Sure it's handy to have tools which automate some repetitive aspects, but if you understand the underlying principles and you know the syntax of the language you're working with, you should at all times be able to just "get it done" however you know how without reading endless documentation and shoehorning your knowledge through a bunch of layers of abstraction.
The same goes for ORM - I want convenience of access to my data, and some automation to handle some of the more boring aspects of writing SQL, but I need to be able to mix and match (yes I know most ORMs allow you to use raw SQL, but it's always one or the other - the ORM or the SQL - I've never used a tool that has a simple method for me to extend the ORM bits halfway through the query building process with some custom SQL).
This is my zeitgeist now and it pervades all the projects I'm working on.
Well, I am not sure if this is exactly what you're looking for, but Django's ORM allows you to write custom SQL and then collect the resulting rows as objects. You can also circumvent the object layer entirely and deal directly with the SQL. Take a look at this page:
https://docs.djangoproject.com/en/dev/topics/db/sql/
I have found this functionality to be incredibly valuable for quite a few of the projects that I have worked on.
function something(db_obj)
print db_obj.getSql() #shows SQL built so far
db_obj.having('SOMETHING = SOMETHING ELSE')
db_obj.fromClause(this.bizarreCaseStatement()
db_obj.order(this.weirdoOrderClauseThatReferencesCaseStatement());
return db_obj
When I start working with db_obj, it might come from some other part of the application for which the "basic ORM" was just fine.Now I want to add some weirdo custom stuff in but I can't - I have to go back to the part of the application that produced db_obj in the first place and refactor that to use custom SQL.
It's one or the other.
enabled = User.where(:disabled => false)
enabled.group("date(created_at)").having("created_at > ?", 1.month.ago).order(weird_order_clause).limit(5)http://magicscalingsprinkles.wordpress.com/2010/01/28/why-i-...
https://github.com/mikecao/sparrow
It's a simple class that builds and executes SQL, but you can customize query at any time.
[1] https://github.com/kla/php-activerecord
$u = new User(); $u->id = 69; $u->retrieve(true)->having( )->orderBy( )->resume();
something like that :)
see: https://docs.djangoproject.com/en/1.3/topics/db/queries/#com... https://docs.djangoproject.com/en/dev/topics/db/queries/#fil...
https://github.com/iaindooley/Anorm
The ORM for SQL lovers!
That's only half the story: I've done the "query reader". Hopefully we can all come up with the ultimate "query builder" together - but the basic principle is that the query reader and query builder should be kept completely separate with SQL as their interface.
I also need to come up with a neat way using closures to "mix-in" functionality to the "query row" objects (that take the place of the normal "boiler plate" DbObject type classes (usually "one per table" kind of deal).
What do y'all reckon? Email iain@workingsoftware.com.au or fork the project - would love to hear everyone's opinions.
Thanks for the heads up! (name suggestions welcome :)
Abnorm.
Any excuse to get away from SQLAlchemy is a good one in my book.
"Well, if it were Python and not PHP, you'd have a customer. :)"
This from the README:
Anorm is implemented here using PHP, however it was so easy to build (only took me an hour to write the actual code) that I would encourage others to use a similar pattern and implement it in other languages.
Fork and enjoy! I'd love to see this same pattern implemented in a bunch of different languages
The code in between those should be as small as possible and as simple as possible, and as obvious as possible given the point of view of someone who knows nothing about your application architecture, to give you the best chance of fixing the bugs in the places that it matters.
A framework tries to occupy the space in between those 2 wires, and unfortunately for frameworks are very rarely small and simple.
Quite a few start out that way, but for whatever reason feature-creep sets in and soon your off to J2EE land.
If you start seeing more than one or two books covering a framework it's time to find a simpler one.
For Ruby, there's Innate, a light-weight framework, and on top of that is built Ramaze, a more developed framework (though still comparatively light). Likewise there is Sinatra, and on top of that was built Padrino.
And both Innate and Sinatra are built on top of Rack. So if you don't care for the direction or feel of a framework you can pop down the layers once or twice and build something you like without having to start completely from scratch.
I disagree with this. Completely abstracting away HTML is a mistake but some level of abstraction like a template engine is highly useful. I can hardly work without some "control" abstraction for form elements to handle setting the attributes and ensuring the form values persist between requests. Template engines can vastly improve the security of your code by making value substitutions safe by default.
The problem with most frameworks, in my opinion, isn't the abstraction part at all. It's that they're over-engineered. It seems like many frameworks approach Turing completeness as they attempt to solve more and more problems and you end up writing framework programs from within your program. Sometimes you even get to use XML for this purpose.
To me this falls under the category of "automation of repetitive tasks" - so long as I'm still fundamentally working with markup in my templates, a bit of automation never goes astray!
<label>Date:</label><ctl:DateBox id="Date" />
<label>Name:</label><ctl:TextBox id="Name" />
...is an abstraction. I think your claim that you don't like abstractions isn't right; you just prefer a specific level of abstraction. Abstraction and automating repetitive tasks tends to go together -- you are specifically hiding repetitive details so you don't have to deal with them. Now some people completely abstract away HTML with something like Haml; but I personally prefer something lower level than that.That's the type of abstraction that I'm specifically opposing here.
Each node in my template should correlate to one node in the resulting markup.
In other words, my "HTML template guy" should be able to construct the interface in it's entirety, with my "developer guy" adding in the functionality.
The "HTML Template guy" should not need to know what type of markup he's allowed to use in order to allow the developer guy to deploy his templates with ctl:DateBox.
That's pretty limited though. A <ctl:TextBox> might be one-to-one to an HTML <input type="textbox"> but it's extremely useful for not repeating yourself to have controls that are much more complicated than that. For example, my Datebox control has an automatic JavaScript popup calendar. I could write code to do that over and over and over in every template but that's a huge waste of time and effort. I'm not sure why anyone would be against that.
The thing is that, with JavaScript libraries as they are these days, "the code to create a calendar popup" is basically already a library.
Also, the person who's going to be creating that interface needs the freedom to be able to decide how they want to solve that problem, for that interface. Having a library of ways you've done it in the past allows you to re-use solutions.
If you find that you have a common chunk of code that you use everywhere on one particular project, put it in an include - but creating "widgets" like this, in my experience, always leads to problems when working with more than one person on a project.
Exactly. All my widgets use jQuery and whatever libraries exist for things like calendar popups. But the library is still somewhat low-level; if I want to use a date field (and my application has many date fields) I have to type a hell of a lot of nearly identical boilerplate HTML and JavaScript for each instance. With a simple abstraction, all that trouble goes away. Even better, if I want to swap out the calendar library (which has, in fact, actually happened) then I can do so in just one place.
> If you find that you have a common chunk of code that you use everywhere on one particular project, put it in an include
That's insufficient. Very few things can simply be dropped into an include and used effectively. Code reuse sometimes requires more than simply calling a function.
> but creating "widgets" like this, in my experience, always leads to problems when working with more than one person on a project.
I find the opposite; the widget is a self contained reusable item -- it could not be easier for other people to use in a project. It automatically promotes consistency. Desktop applications are built this way and there's nothing worse than a project that doesn't use the standard widgets.
You know that you could just do something like "$('.datefield').makeThisADateField()"?
Although I do agree with your point.
There are good abstractions and bad abstractions. If you use and create good ones, you will be a better developer. It´s important not to overdo it or to use the wrong abstraction for the job, but there are alternatives to slogging aroud in html and sql all day.
By using a good orm and language abstractions like haml or coffeescript, I produce much, much less code, it´s much easier to read and maintain, and I can produce more quicker for clients as a result. If another developer can´t look at haml or coffeescript and understand it very quickly, I wouldn´t want them working on my code anyway.
I can also produce more for clients by building even higher level abstractions so I can do things like generate forms, views, lists etc. for 30 different kinds of objects from a couple configuration files instead of hundreds of individual files for each type. Is the coding harder? Sometimes. But it also makes possible features and data usage that wouldn´t otherwise be realistic and allows for rapid modifications to the whole system without searching for dependencies all over the place.
All levels of the web stack are an abstraction of some form right down to the chip. In the future, we will inevitably adopt higher and higher levels of abstraction in our computing, just as we have since computers were invented. Abstraction should be studied, practiced, and used with care, not resisted.
Yes but it cuts both ways. The reason people hate maintaining your code is because they have to learn the way you did things which is buggier and half-baked compared to the way that any number of battle-tested open source frameworks did it. Not because your way isn't good, but because it just doesn't have the mileage yet.
> the biggest conclusion that I've come to is that the best tools are those that enable you to do things faster or more conveniently but don't actually provide any abstraction.
An interesting conclusion, but not nuanced enough. There's no escaping the need for abstractions, obviously there are some that you're taking for granted here such as high level programming languages and operating systems. Fair enough to set those aside.
But then once you get into serious application-level territory you still have to decide where to abstract. Some abstractions are more leaky than others, some are more restricting than others. The art of it is figuring out which make sense in what scenarios. A really good framework hits the right abstractions for a wide range of applications, but even within your custom application you have decisions to make.
For instance, you're one-helper = one-html tag rule of thumb might be a good idea if you have 5 forms on your website. On the other hand if you have 500 CRUD forms all with a bunch of repeated composited HTML structures then it's probably not such a good idea.
I think what's underlying your conclusion is that you've seen too many frameworks that are way too complicated for the problem at hand. That's clearly what the OA saw, and that was really the selling point that launched Rails rise to prominence in the J2EE era. Modern web frameworks have really learned this lesson. Granted, Rails has gotten more enterprisey over the years—but not gratuitously—Rails core has demonstrated remarkable restraint over the years, and kept the focus on solving the 80% problems elegantly.
But if something like Rails really is too much then you have micro-frameworks like Sinatra that really just give you the barebones structure to wire some code to a web server. Heck, due to the modularization of Rails and the extraction of libraries where applicable (eg. Rack), you can now avoid a formal framework entirely and still utilize a massive amount of code that was originally written in frameworks, now in stand-alone library form.
When programmers trot out the old adage "use the right tool for the job", one of the main points is to avoid the human tendency to over-generalize. To be the best programmer you can be, you should be constantly re-evaluating your opinions about the "right" and "wrong" way to do things. Rather than forming concrete opinions, it will serve you better to understand the pros and cons of any approach so that you can effectively apply your knowledge new situations.
I imagine if he had seen something like Play!, he'd have a very different opinion.
It's also under active development and the community is quite strong.
Seriously, people are starting NEW projects with Java as the language of choice? Despite the plethora of 'better' languages you can run on a JVM.
- First it's from 2005 (when was Java made open source.. 2006?). I'm no expert in the JVM but I guess any signifcant community gains where made after 2006.
- Secondly he makes it perfectly clear he no choice "yes, it has to be Java, for a variety of reasons that I don't feel like going into right now"
That aside many people still choose Java for various reasons over other languages. Hell I'm still doing .net 1.1 and VB6 work for clients.
1) Almost everyone knows it so hiring is easy. 2) There's a very large community that supports its tools, infrastructure and libraries. 3) It's faster then almost anything else out there. 4) It has migration routes (via Scala or Clojure) to sexier languages.
As far as I can tell, the only drawbacks to Java are that it's not cool, that's it's verbose and that's it's ugly. Any half decent editor or IDE takes care of the verboseness issues, leaving just cool and ugly, which really aren't good criteria for picking a language. Java was once cool too, and someday Ruby or whatever the current hotness is will also become uncool.
ThingBuilderFactoryActionMethodObject is a certainly an exaggeration, but not that much.
Yes, hundreds of thousands, if not millions of people do. The vast majority of business applications are written in Java, and huge new projects are started with it each day.
"as the language of choice?"
That is a point that is completely disjoint from the first part of the statement. Only a very small percentage of all developers gets to choose what languages they work with.
People that get hurt most are those that believe a framework is a short-cut to learning how to do certain things. You absolutely need to know what's happening under the hood.
The benefits to a developer that is working by himself might be very small if there are any. I guess it depends on how high-level we need to go.
When creation mages see a problem, they create a solution. The power of their mind allows them to come up with the exact thing that needs to be created for the given problem. Their creation skills are honed so well that they get incredibly fast. They don't need to look around much since there's no point in paying attention to what they have created before. Their old creations already solved their problems, they work, they don't have to be disturbed again. Of course creation mages are not stupid, they simply tend to focus on a direct path towards a solution. If some mana could be easily saved by using something already created, they certainly wouldn't pass it up. They would reuse what they've already built. There are just way too many things around them, and it's hard to determine if something fits. After all, they have to keep going without delays. A good creation mage has learned to keep things sufficiently neat. They frequently remember things that they could reuse here and there. However, when one observes any such mage at work, one often sees a lot of mess. Some of the mess has occasional patterns, some things are interconnected, but for the most part it's a very complicated and disconnected system of various moving parts working autonomously to solve their individual problems.
Alteration mages work a bit differently. They are often slower than creation mages, especially in the beginning. That's because they spend quite a bit of time studying their surroundings. They take longer to solve a problem. The thing about alteration mages is, they can't handle mess. (They are accustomed to altering, not creating.) There is a certain compulsive quality to their mind, they simply can't relax in the presence of something unnecessary, when something could be altered instead. You'd often see such mage cleaning their workspace leaving it neat and stripped to bare minimum. They don't have many things in their possession, but spend a lot of time learning about potential things out there that they _could_ have if they wanted. Alteration requires deep understanding of systems, something that can never be quite mastered due to such huge variety of abstract models. That's why alteration mages grab onto every opportunity to learn about a new sample system, a way things could be arranged, patterns, frameworks. When a problem arises, they don't simply create a solution, they build a system which naturally causes that solution to occur, along with keeping all the existing problems solved. In other words, if plants don't grow, alteration mages would try to augment their biosphere in a way that achieves harmony, while creationists would simply generate some water.
Both alteration and creation mages gain experience, level up, and become more valueable. However, they learn slightly different skills. Creation mages learn to have high morale, learn to be calm, and treat solutions as black boxes. They learn to trust their own judgement. Alteration mages on the other hand learn a pretty crappy lesson. They learn that most of their decisions turn out to be incorrect. They build out a system and suddenly get attacked with a problem which the system can't accommodate. It happens once in a while, and they struggle to have everything redesigned from scratch. They end up burnt out, because they can't give up their quest for minimalism and elegance. Yet, it's not all that bad.
You see, alteration mages have a very important advantage. They always tend to record their practices and principles. Old and experienced mages would pass on their knowledge to the newbies. The newbies would build upon it to improve elegance of their systems. In essence, an alteration mage is never a lone warrior, they are always standing on the shoulders of the giants that came before them, which is what makes them strong. One of the first things a newbie alteration mage learns is that what they think is right will soon turn out to be wrong. They are too inexperienced to take the multitude of fairly common scenarios into account. At the same time, they quickly learn to be patient. When an elder passes down certain knowledge or framework upon a newbie, it will not be immediately obvious why things have to be the way they are. After some time they finally see that the knowledge of elders has already accounted for so much and in such an elegant manner that they don't need to worry about these problems any longer. They've already been solved by elder alteration mages in the cleanest ways possible, polished by generations of mages that came after them. Some newbies would rebel, against the elders, but only a few lucky ones actually manage to contribute anything useful, albeit this drive of ambition, trial, and error is often what causes major advancements for the whole guild, akin to the evolution process. Eventually, alteration mages manage to outperform their creation colleagues while leaving clean and elegant systems behind. They would sometimes cringe looking at poor creation mages gluing together half-baked solutions to things that are so deeply understood within alteration circles. Their pools of mana are not nearly as deep as of these performant creation wizards, but mana pools are just a small part of their power. Majority of it comes from the knowledge of frameworks. Certainly, if a problem is completely out of ordinary, they may resort to some creation magic, but for the most part you can count on them walking that extra mile towards finding a well-integrated solution.
I have one issue with your classification however: I can't see where I fit: first, I have little mana. Second, I find alteration magic extremely difficult. I simply cannot comprehend more than the smaller artefacts, especially when they have flaws, or when scrolls about them are scarce.
The USSM[1] web site compiler probably represents me best. I wanted to solve the following constraints: control over CSS and HTML, clean URLs, comments are optional. I looked around, heard about Jekill, read some scrolls, and then immediately thought "scrap that, I can do simpler". The current result is less than a 10 feet scroll (~350 lines), and I plan to shrink it further.
Overall, I am obsessed with systematically crafting the smallest artefact that could possibly work. I love the UNIX philosophy: it let me activate extremely powerful artefacts with very little mana of my own. More often than not, I only have to craft a small ring to bind them all to great effect. My ideal would be something like the STEPS project. And I don't know where it could possibly fit: it looks like powerful creation magic, only with next to no mana.
People who are trying to choice a framework by browsing trough feature lists (not even the code) before they have a working prototype (which means understanding of actual algorithms and data structures) are doomed. ^_^
People who're trying to sell you a piles of code "you really-really need" such as J2EE are just cheaters.
btw, no one prevents you from copying the code from any codebase you like, but only if you can read and understand it. My favorite example is libnginx.so - just better APR. ^_^
This, expressed by Martin Fowler: http://martinfowler.com/bliki/FoundationFramework.html and http://martinfowler.com/bliki/HarvestedFramework.html
What frightens me the most is that they honestly think they are doing it right. They really believe Maven is sane and that Hibernate generates good SQL.
Some of them even say "of course we are using Java - what else would we use?"
Even outside of Java-land, Rails had yet to hit 1.0, and Django was just starting. The evolution of the framework has come a long way in 6 years, and frameworks have become less "one size fits all" and more task-appropriate.
I think a more appropriate title for this post is: "Why I Hate circa-2005 Java Frameworks"
While many of his points are valid, his comparison of carpentry to using a framework takes a very select view of what goes into building something. Of course you need a hammer to build a house, just like you need an if-else statement to build a webpage.
If you're building a 10 page webapp (spicerack ) you probably don't need a framework. If you're building a full-fledged web-system (house) you don't need a framework, but you'll be much more productive for having one.
http://news.ycombinator.com/item?id=2516940
I actually think that at the time, the servlet spec, jsp, and jdbc were reasonably good, productive ways to write software. It was admittedly verbose and laborious compared to modern languages and frameworks like Rails or Django (I'd also agree it was verbose compared to PHP and Python at the time), but it wasn't a depressingly long setup that was hard to even contemplate for simple apps. It was only a little more complicated, and it did come with some benefits.
My advice to programmers who are curious about what has become of Java is to go to the springsource home page, and work through the MVC tutorial. If you agree that this is a reasonable way to write software, then you'll disagree with me that web application with Spring has become too complicated.
I actually think that if you were willing to go back to the original servlet spec, and use libraries, Java wouldn't be quite so bad. You can still pick and choose, and you're not at all obligated to use Spring. There are better MVC frameworks out there.
To me, I don't really see the point, though. I know, there are problems that have already been solved, why re-solve them... I think maybe some people have more mental trouble with what another poster called "shoehorning your knowledge through the various abstractions of a framework" (I'm paraphrasing here). I've done this with Spring and Struts 2 (a different product entirely from Struts), and it was unpleasant. I've done this with Rails, and while I like Rails a lot and consider the trade-off worth it, I still never really felt in control (maybe I would if I used it more).
If I use Java, I'd prefer to just go back to the 2004 days, write servlets, and build from there with libraries. I do like Dependency Injection, so I'd probably have to use some kind of framework - maybe Juice?
But really, even though I prefer to be at a lower level and don't like frameworks, I think the future for people like me is Sinatra and/or webpy. Nothing really stopping me from doing more "low level" programming in those languages, trading efficiency for a code base that I really understand through and through.
That said, the difference between that approach and Java circa-2004 isn't as great as the difference between, say, Rails and Spring. Once you need (or just want) to drop to a lower level of code, I really don't think Java is all that bad.
To perhaps extend the metaphor, if I want to build a spice rack, I don't want to go out into the forest, determine which kind of tree will produce the correct kind of wood, cut it down, trim and plane my planks, and all the other steps which are entailed by wood acquisition. I just want to go to my local hardware/home improvement store and request precut wood.
This poster has gone ahead and made assumptions about the nature of resource acquisition which massively simplified his workload and which people normally take for granted in modern life, and as a result, his spice rack will get assembled much quicker. I'm choosing the networking stack as a reasonable example of a framework niche which generally fulfills people's needs without getting in the way and causing the problems he's talking about. Node, Event Machine, Twisted, MINA, etc.
What's important is using the right tools for the job. Sometimes you might need the high level, very abstract framework, but it's not cool if that ends up being the only tool available.
$framework->outputTextInput("name", "value", "class");
And after running +50 lines of code this would be the output: <input type="text" name="name" value="value" class="class"/>
It had nothing to do with keeping the state of the app or something, just outputting HTML...