I don't always see the need for a framework, but once you've gone through the process of learning the ins and outs of one, which does indeed take extra time the first time around, it's a familiar tool and can really speed things up when you re-use it in the future. Now if you try out a new framework on every new project, that's a different story...
For example, I ripped NHibernate out of a project because the SQLite database only had 6 tables. (Later reduced to 3 tables.) In this case:
- The original author used NHibernate incorrectly, making the product 10,000x slower then it should be
- There's a high learning curve to NHibernate that all newcomers to the project must go through
- There's a risk of having to work around an NHibernate bug
- We have to ship NHibernate and adapt to new versions or potential security holes
- The lawyers have to approve of the NHibernate license
- A small, infrequently updated xml file using built-in serializers is much easier to work with then SQLite + NHibernate.
Sure, we probably have about 1000 lines of DAL code instead of 200 lines of hbm files; but it's DAL code that's bug-free and has no external dependency risk.
Would I use NHibernate, or a different DAL framework, in a different context? Sure! If we had many more tables, and changed our schema frequently, it would be the correct thing to use. It's all about understanding when to use a framework versus a library.
To me, the defining feature of a framework (as opposed to an ordinary library) is that it’s explicitly not compositional, not replaceable, and not a “good citizen” for interoperation. Doesn’t sound great.
But there is a valid reason to incur these costs: prefab solutions let you ship something basically good now. The same thing happens in game development: do you just write a game, reinventing a lot of architecture now, or do you choose an engine, working around its limitations later? It’s more of a business decision than a technical one.
It's even easier when hiring because a big portion of your training is already done before the person is hired and they are knowledgeable in said framework.
- Confusing design patterns with frameworks
- Using frameworks incorrectly
- Using a framework when a library is more appropriate
For example, Dependency Injection should start as a design pattern, and then a framework brought in based on the project's requirements. A couple of screens of "new" statements have very little learning overhead. No framework can define the way an application's modules relate with each other.