A recent conversation happened in my workplace about how one defines a framework. More often than not, software developers and architects tend to call their code as "frameworks" if it is reused (or in many cases, they they can potentially be reused without any proof) across multiple applications.
A quick search through Stack Overflow provided an explanation I thought was helpful.
When writing code:
- eventually you discover sections of code that you're repeating in your program, so you refactor those into Functions/Methods.
- eventually, after having written a few programs, you find yourself copying functions you already made into new programs. To save yourself time you bundle those functions into Libraries.
- eventually you find yourself creating the same kind of user interfaces every time you make use of certain libraries. So you refactor your work and create a Toolkit that allows you to create your UIs more easily from generic method calls.
- eventually, you've written so many apps that use the same tool kits and libraries that you create a Framework that has a generic version of this boilerplate code already provided so all you need to do is design the look of the UI and handle the events that result from user interaction.
Another reference puts this in a visual context:
Additional thoughts
One interesting point made in the second post is that a telling (but not necessarily the only) characteristic of a framework is that it has Inversion of Control (it calls the app than the other way around). Frameworks tend to do a lot of the 'plumbing' work that is necessary for a software application while the developer needs to focus only on extending or leveraging the work at the right places (knowing where to put the faucets, in the plumbing analogy).
What is probably missing in this picture is the notion of a "service", but in this context, it can simply be taken as a more abstract form of a "library", as it possesses the same characteristics. If a use of a library spans across multiple platforms and technologies, it can potentially be abstracted further as a service.
The description below also nicely conforms to the "three-box principle" that I learned a long time back, which states that you cannot get to libraries / tool kits / frameworks without having done or at least thought through multiple (at least three) implementations.