The interpreter behavioral pattern allows you to solve common problems by expressing those problems in a simple language.
You first need enough problems to make this pattern worthwhile. And this pattern is great for allowing other people to contribute to your application without writing actual code. You define a language that can be used to describe different problems sort of like how a math formula solves a problem. You have different math formulas to solve different kinds of problems. And each formula can solve different specific problems by substituting different values into the formula.
This pattern relies heavily on the composite design pattern. In fact, it’s really just a composite structure where the objects are instances of classes representing the rules of your language. This is called your grammar. Each of these objects defines a method called evaluate that needs a context to be passed to the method. The context is just the specific values that you want to evaluate. The composite pattern is great for calling the evaluate method for each object in the structure.
That’s all there is to this pattern. It’s a simple pattern with a complicated description though in the Gang of Four book. This episode provides more information with an example from the adventure game. I explain how you can use this pattern to solve a wide array of spell effects and even how to let game designers have direct input into how the spells work by writing formulas that can be interpreted with this pattern. Listen to the full episode or you can also read the full transcript below.
The basic description says that this pattern begins with a grammar then defines a representation for that grammar as well as an interpreter and then uses the interpreter to interpret sentences. Wow, I think I confused myself on that one.
Let me explain this in a completely different way that hopefully we can both understand. And if my explanation doesn’t quite fit with what the gang of four intended, then I say it’s their fault for writing such a ridiculous description. This is a pattern that without somebody to explain it, we would all, yes, even me, just drift off into a daze.
Okay, here it goes. I’ll start with a description of a problem and then show how you might use this pattern to help.
First of all, you need a bunch of common problems. If all you have is a single or even a fixed number of specific problems, then you’re probably better off writing specific code to solve them. This pattern applies when you have enough problems that you get tired of solving them and they’re all similar and not very complicated.
What kind of problems? Well, let’s take the adventure game as an example and say we want to allow for many different kinds of magic spells that can be cast on a distant target. And let’s also say that the spell behavior should change as the hero gains experience and gets better.
Now, if you only have a couple spells, maybe one throws a ball of fire and another shoots lightning, then you might be better off representing these with their own classes. But if you have game designers that are conspiring against you by coming up with new spells almost daily, then you’re going to need a better solution.
Programmers, you see, have a special kind of laziness. We’ll work really hard to automate something so we don’t have to do that work anymore. And a really good way to avoid work is to get those designers to do it instead.
So how should you approach this. Well, this pattern says we need a language. A grammar is just the rules that define a language. Our spell language will probably need things like level, distance, spread, immediate effect, and ongoing effect. Maybe more but this should be good enough for this explanation.
◦ Level will define how experienced the hero is.
◦ Distance will define how far the spell can reach and should increase based on level.
◦ Spread will define how widespread the effects become as the distance increases.
◦ Immediate effect defines the results of the spell that happen the moment it reaches the target.
◦ And ongoing effect defines any lingering effects.
I’m not going to get into the actual rules for the grammar in this episode. Just know that you need to define how to express the spells with these factors. Think of them sort of like mathematical formulas. Each spell will have a different formula. Fireballs will spread out as they get farther away. While lightning will tend to remain tightly focused.
The point of the grammar is to set some rules for your language so the designers can’t just send you nonsense. It should be flexible enough though to express a wide variety of scenarios. The designers will love the feeling of being able to define their creations and you’ll love all the work you end up saving.
Now that you have this new language, I’ll explain how to actually make use of it right after this message from our sponsor.
( Message from Sponsor )
Episode 66 describes the composite pattern which plays a big role in this pattern. In fact, this whole pattern is really nothing more than just a specific implementation of the composite pattern. Make sure you listen to that episode to get the full benefit.
You see, when you have a particular instance of your language, which in our case is a spell effect formula, this can be represented with classes that build on each other. You construct a composite formula where the objects in the composite are instances of the grammar rules.
The interpreter pattern really is just a composite. But not all composites are interpreters. Whenever you have a composite that’s built up of language rules, then you have the basis for the interpreter. All you need to complete the picture is some context and an evaluate method.
Some spells will be completely different from each other even though they still follow the same language. If they don’t fit the language, then you might need to evaluate if you have enough of them to justify yet another language. But assuming for now that they fit, then different types of spells will just have a different formula. Each formula is just a different composite structure.
Some spells might follow the same formula but with some different values. Maybe a weak fireball spell behaves just like its big brother the fireball spell but with less range and less damage. Both of these would share the same formula but with different values. The values are the context. And factors such as the experience of the hero also belong to the context.
Your code that’s managing the game needs to keep track of the context but that should be information you have available. Then it passes the context to the evaluate method in the composite formula. You might need to perform the evaluation for each possible target to see if any are affected by the spell and by how much.
The important point to all this though is that with this pattern, you’re able to reduce what would normally be a confusing mess of ever increasing problems and their solutions down to a simple language that can be evaluated.