Representing State as interfaces in Go - Evan Moses

submited by
Style Pass
2024-03-28 06:00:02

I made up a neat little pattern in Go the other day. It’s a way to represent a state change in a system by exposing different APIs for different states, while only holding state in a single underlying struct. I’m sure I’m not the first person to invent this, and it may already a name, so please let me know if you know of one. I’m going to show an instance of the pattern first and the motivation after.

So far, so boring. You’ve got a Resolver that batches up query data, an Executor that, well, executes the query, and a Resolve that lets you access the result. What’s neat about this is that Resolver and Resolved can be implemented by the same struct:

I was building a system to bulk-lookup names in my system by ID. But if you called Resolve before it had executed, you’d have an invalid result. And if you Collected after you executed, you’d never look up the id. So I added a boolean hasExecuted to IdResolver so that if you called Resolve before you had called Execute or Collect after, it would check that flag and panic.

Of course the Resolver and the Resolved could be represented by different structs with their own methods. But in this case it felt like we were really working with a single object: it collects data, operates on it, and manages the result.

Leave a Comment