When given the choice between using a library or adopting a framework to accomplish a task, the choice is often between the power and usability. Libraries often focus on simplifying a task by providing a layer of abstraction, where frameworks focus on making categories of tasks easy. For integrating with existing applications, it’s more difficult to use multiple frameworks than it is to use multiple libraries. But when starting a new application, it’s often easier to pick a framework and then select libraries that can easily inter-operate where the framework doesn’t provide a solution. So the library vs. framework question is more a function of context than one of interfaces. Picking the right tool for the job requires knowing the job and the tool’s capabilities within the larger context.
The argument for simplicity is that the tool shouldn’t do more than necessary. Choosing a library or framework that provides unwanted functionality can influence the future direction of the application and add unnecessary complexity. This makes tool selection a difficult forecasting decision, where picking a tool for the problem at hand becomes picking a tool for future problems as well. For example, when looking for a tool that will support an event driven data flow, picking a cross-platform GUI framework will naturally cause the application to shift towards user interaction and display because that’s what the framework makes easiest. The choice of a framework over a simpler library will also influences how other parts of the application are handled as well, as the framework might provide tools that can be adapted to solve unforeseen problems. It would be impractical to choose a library or framework and then not fully utilize it to solve current problems efficiently, it’s natural to fully utilize the tools available even if they aren’t the best tool for the job. If instead for the above example, a simpler eventing library was chosen; the natural tendency would be to build much of the core data flow with events as that would be the only tool available. Then, when the current tools become insufficient to solve a problem, decide on another tool as the problems arise. The direction of the application’s development would then be more heavily influenced by external factors such as customer requirements or developer experience than the strengths and weaknesses of the current tool choices. This sort of minimalistic simplicity follows in the steps of YAGNI and premature-generalization, where taking options away makes the problem more constrained and easier to solve over an intractable selection of options. This partially applies to language environments, where the choice of language will have an even bigger impact on the tool and framework selection. Disuse of language features is more commonly enforced than library or framework components, as discouraging use of certain undesired features like exceptions, certain data types, or global variables has an immediate visible impact on performance, safety, and maintainability. Library or framework features are generally less governed or recognized as influencing the structure of the program.
The same argument could be taken to the extreme and applied to gadgets in real-life! Instead of buying a device that provides multiple functions, one could get multiple devices that provide the same function in aggregate. This would provide both fault tolerance and independence. Instead of arguing over the framework (the OS), it would be better to only talk about the applications. But because the framework is so influential, the selection and functionality of the applications available for a framework can be completely different!
This has been a long justification for my use of a feature-phone and GPS device. It’s been a year since I first posted that I’d explain why I use the tools I do, so I’ve finally gotten around to laying it out with a technical analogy. My only hope on the horizon is the Ubuntu phone, which will hopefully be as close to a universally adaptable framework as possible.