Plugin-based applications (by alaric)
I've noticed that some of the best applications I've used (or designed) have been ones with a decent plugin architecture.
In designing applications, I've often noticed that as soon as we add a plugin system, we start to notice that large parts of the app could just be turned into plugins; and if we get time to do this, before long, we have a very simple and generic 'core' with lots of plugins.
This is good, since it tends to reinforce the internal boundaries in the application. It ensures that there aren't any unexpected dependencies between modules.
Ooh, I just said module. Module? Plugin? What's the difference?
Well, the difference I'm setting out to make in this post is that a bit of software is, at least in the design state, split into modules, each of which interacts with other modules only through documented interfaces. So the top-level designer of a bit of software takes a specification for the whole thing and produces a set of specifications for modules, each with their exposed interface, explaining how the modules can use each other's interfaces to provide the functionality required of the software.
However, often, there will be several modules which provide the same interface. For example, there are various formats for specifying rich text; RTF, HTML, Markdown, etc. A web publishing app (such as this blog) might have modules to implement each, all with the same interface: given a bit of text, return a rendition of that text in HTML for sending to the browser.
In those cases, it becomes sensible to replace that set of modules with a plugin registry. The user of the software can, using any of a number of actual mechanisms (dynamic linking, including in interpreted languages, etc) install any number of such modules as plugins by registering them in some kind of list (which can be as simple as "dump the plugin file into a specified directory"). The rest of the system is written with no knowledge of which plugins will be actually available; it only finds out when the application is run.
The first application I came across this with was a content management system called OmniSite. We wanted to provide a choice of rich text formatting operations, so we decided to make a plugin registry for them. We then noticed that the authentication system could be gutted and replaced with a plugin system, too; by default we'd supply a local-database-of-users plugin, but it was then possible for customers to write their own plugins that would access their existing databases of users. We had a sort of scripting language for HTML page templates built in, so we split that out into a plugin system, allowing other templating languages to be used; eg, to create image templates (that generated PNGs on the fly) or PDF templates. Or zipfile templates.
As this process continued, a large application quickly broke down into a fairly simple set of libraries to handle our database structure, an admin site for editing the database, the plugin registry system itself (which kept a list of installed plugins of each 'type' - authentication, rich text, page template, etc), and a 'view public page' script that really just consisted of running the authentication plugin to get the user's details if there was a session open, loading the page data from the database, seeing which template language the page was written in, and invoking the template with the user, session, and page data. The template would then invoke rich text plugins to process rich text fields, and so on.
This actually made the app much easier to write. Plugins could be developed in isolation.
An example that's actually available for people to download nowadays is TextMate. It's a text editor, with a well-developed and powerful plugin architecture, and as such lots of people have written plugins, and contributed them back. So TextMate supports a lot of languages and developer tools, in very pleasant ways.