Tool vs Framework practice
In line with my results vs system thinking exploration, I think I’ve found what may be another dichotomy in software development practice. The tool over framework principle has been fundamental for my engineering practice for my whole professional career. Composable tools have served me better than large frameworks. Usually I’ve considered it a style choice with consequences, but it may represent a more fundamental attitude towards engineering. Even if your system doesn’t use an explicit 3rd party software framework, the framework way of thinking may be present. As always, this is not a black & white descriptor.
Tools
- Unix principle: do one thing and do it well
- Composable tools provide platform as needed.
- Enable and empower.
- Give developers tools to build with.
- Intimately familiar with tools.
- Likes new tools, actively adopts them.
- Likes the command line.
- Learns by reading source and documentation.
- Vertical development.
Benefits
- Flexibility.
- Reusable and composible functionality. Encapsulation.
- Application performance from choosing only the tools needed.
- Adoption of new tools rather than building.
- Reduce costs by leveraging the best tools.
Costs
- Upfront investment in learning multiple tools
- Fragmentation of implementation.
- Emergent behavior between tools and components.
- Complexity of system.
- Fragility
Frameworks
- Microsoft principle: play in our garden, it’s got everything you could need
- convention over configuration.
- Insulate and focus.
- Give developers places to slot in logic. Frameworks provide all platform details.
- Likes IDEs.
- Always wants familiar tools. Distrusts new tools or new uses of tools.
- Learn tools to the level that the benefit is achieved, no further.
- Learns by example and imitation. Likes recipes and copy/paste.
- Web frameworks as ur-example.
- Horizontal development.
Benefits
- Knowledge transfer between organizations. (“Looking for a Rails developer…”)
- Quick turnaround from idea to something presentable.
- Commercial tools and support.
- Reduce costs by focusing on business logic over implementation details.
Costs
- Founders once framework no longer provides functionality.
- Sprawl and inertia.
- Reiventing the wheel, ineffective tool use.
- Duplication and redundancy.
Horizontal vs vertical
Tool and framework nicely describe an attitude a developer or team has towards their work. There are two descriptors of the software projects themselves I’ve used for a while, which I think very closely map to the tool and framework thinking: I call them vertical and horizontal.
A vertical system has narrowly focused independent components, building up complexity through the combination, usually in a heirarchy. Vertical systems leverage tools appropriate at each component.
Horizontal systems are very flat, with many similar broad components at the same level. Horizontal systems leverage frameworks and use the same set of tools for each component.
The classic example of a horizontal system is one using the typical web framework (Rails, Django, Cake, etc). Ostensibly there are layers (a distinct pattern “Rails-MVC”), but it usually devolves into what I call macaroni code. Each component has a data access system bound to one database table, a routing class, and a UI template. Repeat for every table in your database. Best case, you get these macaroni tubes of functionality from the UI to the datastore. Horizontal development scales well. New functionality can be added without affecting architecture. There is a strong established pattern for devs to follow; it lends itself well to most dev shops and outsourcing firms where developers are mostly low skilled. Functionality is (hopefully) strongly grouped and easy to find. Service oriented architecture to this style means splitting the macaroni into separate processes. Failure modes include; needs beyond the basics of the horizontal layer, problems outside the scope of the framework, unmanageable sprawl, slow moving change. Compare with an assembly line - lots of very similar operations done at a large scale.
Vertical systems are more rare, and less visible due to their general lack of reliance on frameworks. Growth of non-traditional software tools in data analysis, distributed systems, and embedded systems have driven tool development. In the web space, tools like Sinatra and akka-http represent a different approach, providing only routing functionality and expecting other tools to provide for other needs. Akka itself is a great example of providing a set of tools for solving concurrency model problems. Vertical systems are more likely to become spaghetti and fragile, due to the increasing complexity of interconnected components. If each component becomes connected to most of the others, the number of possible connections goes up exponentially. Good vertical systems are build heirarchically, with the complexity managed by abstracting away details of a component’s inner workings and subcomponents. Service oriented architecture to this style is just another way to compose the system components together. Compare with an internal combustion engine - distinct components, working together in a complex way.
- programming