UP | HOME

Software extensibility

Loose coupling is useful, among other things, for practical system/software extensibility; or, in other words, tight coupling complicates it. It's the recent investigation of XMPP client implementations (with some of the issues arising because of restrictive APIs) that made me to consider it this time, though the problem is pervasive. XMPP looks like a nice problem example, since there is a small core, and a set of extensions – all specified and sane, with new ones appearing occasionally, but some of them altering some aspects of the core behaviour (e.g., cancelling resource binding on stream resumption). In its implementation, it would be nice to define the core once, and only extend it with separate modules implementing extensions then; likewise with multi-protocol clients that may use it.

Separating a system into smaller reusable tools with defined responsibilities and APIs (applications, libraries, microservices, actors, generic abstractions available in a given language, etc) helps to some extent on its own, but it's far from a complete solution; as plugin and scripting mechanisms, those still depend on (and are restricted by) resulting APIs, and unforeseen uses are complicated without adjusting the core.

Emacs and Prosody are good examples of highly extensible programs. They provide various ways to customise their behaviour, including common functions and configuration by setting variables, but what distinguishes them is that they allow new modules/packages/modes to alter existing control flows (albeit implicitly) by making use of hooks/advices/events, employing event-driven architecture. libpurple does something similar with signals, but to a lesser extent, and still relying on restrictive APIs and conventions.

In the XMPP example, the core flow (as in RFC 6120) is defined in steps, and it would be sufficient for alteration if those steps (or merely RFC sections) were defined as nodes in an alterable control flow graph. Systems like that may use RDF triples (a database with those, perhaps) as a generic and language-agnostic way to describe and modify the control flow, potentially getting good logging and development documentation for free. Though it may be unnecessarily complicated; as for more traditional approaches, a scriptable program or a library could just provide fine-grained functions for all those steps: then it can be used at least for custom, if not adjustable, control flows.