Nate Meyvis

Notes about encapsulation

I've written about encapsulation many times, but I've never written a post about encapsulation specifically. "Encapsulation" can mean a lot of things, both because it has many aspects and because we sometimes mean slightly different things when we discuss it. Good encapsulation can mean:

  1. That subsystems are communicating only through well-defined, appropriate interfaces;
  2. That responsibilities are divided among subsystems appropriately and, specifically, that one subsystem is not responsible for too many things;
  3. That, if something is wrong with X, you can work in the subsystem responsible for X without having to look inside other subsystems;
  4. That abstraction barriers exist and are enforced.

You could spend a long time distinguishing among these, arguing that some are equivalent, or arguing that one is more important than others. That's well worth doing, but for now, we can consider this rough cluster of ideas.

Getting this right is hard, and we (the industry) have not historically done it well. Many programmers ignore encapsulation, beyond what is minimally necessary to get a system working or to write minimum-viable documentation for it. Even those of us who try not to ignore encapsulation often fail to implement and preserve it properly. This is very bad and expensive, for many reasons, most of which arise from the fact that subsystems get much harder to work with as they get larger and more complex.

The difficulty of working in a subsystem is often approximately quadradic in its size or in how much it's doing. Failing to maintain boundaries between three systems of size N makes it 9, not 3, times as hard to work in, according to this approximation. Yes, this an approximation, but it's an approximation that (i) admits of intuitive justification and (ii) rings true to me. (Actually, I'd take the over on 9 if I had to guess the average real difficulty-amplification factor here.) So as you bloat a subsystem:

  1. Bugs involving that subsystem get a lot harder to diagnose;
  2. That subsystem gets a lot harder to monitor;
  3. It gets a lot harder to change that subsystem...
  4. ...which amplifies the problem, because the changes are likely to entrench or extend the encapsulation problem. The work was way harder than it would have been, and future work is now even harder than that!1

The amplification of flawed design works on many levels. A system that lacks proper encapsulation is harder to reason about, which means it's harder to communicate about and even to think about. This means that:

  1. A new team member might ask, about a hat-management system, "What is the data model describing a hat?" or "If a user enters inconsistent information about a hat, what happens?" These questions can become almost impossible to answer.2
  2. Your tests and documentation are likely to make a lot less sense, which means you're likely to have more brittle tests and worse documentation.
  3. When your system needs to do a new job, handle a new problem, or anything else, you have a much harder time deliberating about it. This is true whether you're at your computer, talking with a team, or thinking about it on a walk.
  4. Because it's harder to understand how you're using your resources or to measure that, it's much harder to improve how you're using those resources.

And on and on. Encapsulation matters a lot. This suggests a bunch of obvious and important questions, three of which are:

  1. Why is encapsulation underrated?
  2. Why do we so often fail at it even when we care about it?
  3. How much can LLMs help us get better encapsulation?3

But each of these would need another post.


  1. There's a sociological angle here, too: work in poorly encapsulated subsystems is likely to be (i) time-consuming relative to its description and (ii) unpleasant, so there will be organizational pressure from several directions to do it hastily and therefore badly. But that's another post.

  2. ...Did I mention that working in poorly encapsulated systems makes programmers much more sad, on average?

  3. There's also a lot to be written about common symptoms and proximate causes of encapsulation failure, but that would answer a different kind of question.

#generative AI #sociology of software #software