Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
The best software fits naturally into the user's existing environment and workflow, making its integration points as seamless as possible. For a great example of the benefits of interoperability, we can take a look at the Rack webserver interface.
Before Rack existed, every web framework in Ruby needed to create an adapter for every web server it supported. As a result, many web frameworks didn't end up supporting a wide variety of servers until they became fairly mature. Of course, many users would not bother to try out a given web framework unless it supported their preferred web servers, so this became a bit of a chicken and egg problem.
Rack solved this problem by establishing a simple abstract interface for handling HTTP requests and responses. Rather than writing adapters for particular web servers, it became possible on the framework side to write a single Rack adapter instead. On the web server side, a single rack handler was all that was needed to expose server functionality to all Rack-based frameworks. This small but powerful abstraction eliminated the complexity involved in writing server-agnostic web frameworks, resulting in a huge gain in interoperability.
While the main purpose of Rack was to make it easy for frameworks and servers to integrate with one another, the interface proved to be useful for other things as well. By removing the direct connection between framework and server, an endless variety of middleware could be inserted between the two. This feature has been used to introduce all sorts of interesting things into the request/response handling chain, ranging from exception handlers to syntax highlighters.
Given that Rack represents a very elegant pattern for facilitating interoperability, I am somewhat surprised we haven't seen similar tools arise in other domains. One area in particular that I'd love to see become more interoperable is our testing frameworks. It seems like the rack analogy could be extended to things like test runners and formatters, if only a common low level interface could be established. This would allow for more tooling to be shared between Test::Unit, MiniTest, RSpec, and the various other frameworks that Ruby programmers use for testing. That said, I've not done more than daydream about this idea, more thought would need to be put into it before I could decide whether it'd be feasible or not.
Speaking generally, whenever we see N projects integrating with M other projects with significant overlap between them, we should ask ourselves whether this sort of pattern might be a good way to increase interoperability while reducing the overall maintenance overhead for each project.
Turn the page if you're taking the linear tour, or feel free to jump around via the sidebar.