Align Responsibilities And Capabilities

Part of Read before contributing, an opinionated guide by William Reade

Align Responsibilities And Capabilities

Interfaces define capabilities; by inspecting the capabilities exposed to a component, you can establish bounds on what it can possibly affect and/or be affected by. (If you’re not familiar with the term “light cone”, look it up, it’s exactly the same idea.)

When framed in these terms, it seems clear that the fewer capabilities we expose to a component, the easier it is to analyse that component, and hopefully that’s reason enough to narrow your interfaces as you go; but if you embrace the concept, you can take it one step further, by treating every capability exposure as a responsibility transfer. That is to say, you only supply a capability to a thing you know will use it.

In concrete, juju-specific terms, consider the environ.Tracker worker. It’s a worker, so it has Kill and Wait methods; and it also exposes an Environ to clients that need one; but the sets of clients are non-overlapping. When you construct such a worker, you get a concrete type exposing both sets of capabilities, and thus become responsible for their discharge; so you put the type under management as a Worker alone, and hand on the Environ capability to whatever else needs it (specifically, in this case, via its Manifold’s Output func).

Similarly, the various worker implementations that start Watchers will pass the worker.Worker responsibility into the Catacomb, leaving only the Changes() channel for the loop func to worry about.

And if you don’t hand on some responsibility/capability, and you don’t leave a comment explaining why, there’s local evidence to suggest that you done goofed; either by handing too many capabilities into the context to begin with, or by dropping a responsibility on the floor.

I’m not sure what concrete advice this boils down to, though. It’s more a mode of analysis, I guess – looking at code explicitly through these eyes can be useful, and can betray opportunities to tighten it up that might not be otherwise apparent.