Imagine some Lego. Or alternatively, think of a non-trademark-infringing equivalent plastic brick product, if you’re concerned about that sort of thing.
So you have this box of Lego. It’s that good old general purpose kind, where almost any kind of block can connect to almost any other kind of block. You can build castles or houses or boats or fluorescent yellow difference engines. It takes a bit of forethought, and occasionally you need to change something you already built to get it to work better, but in the end you have what you wanted. If requirements change, you yank out the bit that’s wrong and put something else in its place. It’s sometimes a slow process, but it’s predictable, well understood, and (most importantly from a developer’s point of view,) interesting to build.
You also have a different box of Lego, one of those official tie-in Star Wars kits. It’s a bit like your original box, but instead of being general purpose these bricks have been counted out in advance and tailored to a particular goal. The kit includes detailed, potentially complicated instructions, but you’re completely free to choose which character pieces you want to have in each room of your Awesome Lego Death Star. Basically, this kit makes one thing, and makes it really well… As long as what you want is what is on the box.
Similarly, there are two different ways to approach a new application development project. You can build an application using a combination of your own code and third party libraries, following your own design and goals. Or you can use a framework and provide a bit of extra code to customize it; the coding equivalent of choosing which Lego character gets to sit next to Vader on your Death Star Command Deck.
So you can design an application to serve a specific purpose, or you can construct an application to look like the picture on the box.
Neither of these are bad options. If you need an application which looks like the design on the kit, then use that framework or the platform or the configurable off-the-shelf product. It’s always good to find a cheaper, faster way to meet your client’s needs. If you have a close fit with an existing system or platform, and the changes you want to make are compatible with that system’s requirements, then that’s awesome. Lego Death Star for the win!
But if you want something that looks quite a bit different to the picture on the box, there are some things you need to consider:
Using a framework probably won’t save you time. Often, people spend about the same amount of time building something from a scratch as they would learning the theory behind the framework, catering to its particular requirements, and trying to trick it into doing something that it wasn’t designed to do.
Using a framework probably won’t save you from bugs. If it were a pure numbers game, the framework solution might seem to win, because you’ll probably have fewer bugs overall. But most developers will agree that they’d rather fix a dozen null pointers or class cast exceptions in their code, than try to debug one cryptic runtime error from deep in a framework. Framework error messages often have hundreds of lines of stack trace before you even see a hint of something you know about, and you need to spend a lot of time learning how the framework magic works in order to understand what those errors are even about. In the horrible situation where the problem is actually in the third party code, you have to introduce hacks into your own code just to make things work!
Using a framework probably won’t reduce complexity. In order to be relevant to more than one application, a framework has to include a lot of code which you probably don’t need. Does your application need a wiki? No worries, this framework can give you a wiki! And a forum, and photo sharing, and a recipe database, and a social gaming platform… Of course, in order to stop having those things, you will almost certainly need to add more configuration. Turning functionality off can also have unexpected side effects, like buttons which take you to disabled screens, or back-ends which try to read files they’ve never written. Having behaviour in your application that you don’t need is a rich source for wasted resources. Having behaviour which you actively don’t want is almost guaranteed to cause you pain.
Using a framework won’t make you more innovative, or more agile. If you’re using a framework, it’s because you’re solving a problem which has already been solved. By the framework. That’s not being innovative. The basic premise behind a framework is that it makes expected things easier by making everything else harder, and the ‘everything else’ is the place where you can differentiate your product from everyone else’s. In order to be agile, you often need to adapt to customer requirements you don’t know about in advance. If your client decides they want something that your framework didn’t provide for, you’re in trouble.
Using a framework probably won’t make it any easier to find good, experienced people. Anyone who can code Java, can code Java. The more third party frameworks you expect developers to be fluent in before they start though, the smaller the pool of experienced developers becomes. You either end up taking what you can get, or you can lose weeks of time before starting your project, waiting for your developers to learn enough of the framework to actually do the work.
Using a framework probably won’t make it easier to keep good, experienced people. I’m not talking about the “get trained on company time, then go somewhere which pays more” scenario (although that is a valid concern). I’m talking about developer boredom. Why do you think there are so many frameworks out there which no one uses? It’s not because we need that many frameworks, it’s because developers enjoy coding interesting things. Compared to that, how do developers feel about adjusting framework configuration property files, or searching the web trying to find out what the weird error the framework just spat out is a known defect or not?
Using a framework probably won’t make your team more productive.
If your project is noticably different to the demo app provided by the framework you’re considering, you’ll probably end up paying the cost of that framework a dozen times over in time, limitations, and frustrations.
Frameworks are not all bad. In some cases, they are an absolute godsend. But they are horribly overused and misused in the name of ‘best practice’. In a rush to replicate another person’s success, people frequently forget to think hard about how close the framework’s fit is to their own project. “I know someone who used it on their project, and it worked well for them” is not the most important consideration in the decision making process.
Does the framework actually do what I need for the application I want to do?
Does it do too much?
Is it based on a lot of magic that I’ll need to learn before I can debug my own code?
Is it going to restrict me in a part of the application where I need to be flexible?
Is it going to tie me to a platform or technology that might cause me complications down the track?
If I change my mind, how hard will it be to stop using this framework?
Am I actually going to enjoy developing within this framework’s structure/rules/limitations a year from now, once the initial shiny newness wears off?
Am I trying to tweak someone else’s Death Star, or to design a wholly original Lego Space Rocket?