Command pattern done with generators~ Design patterns ~

Command pattern done with generators

I spent some time thinking about how to finish the book. What will be the last chapter? And to be honest, most of those 50 topics deserve to close the book. I picked the command pattern implemented with generators. I saw it for the first time when I used the redux-saga library. It is based entirely on generators. I became a fan of the approach.

The idea of the command pattern is to separate the objects that trigger logic from the objects that implement it. The trivial variant involves a function and a switch statement that decides what needs to be done. The following snippet shows the triggering bit:

function* logic() {
  const name = yield ["get:name"];
  const user = yield ["get:user", name];
  console.log(`Hey ${user.firstName} ${user.lastName}`);
}

"get:name" and "get:user" are the so-called commands. Those are the instruction. The idea is to get a name as a string and then receive a user object containing that same string split into first and last name. See how here we don't do the name fetching and splitting. We also don't create the user object. We only declare what we want to happen without doing it.

Here is the generator that receives the commands and executes them:

function processor(gen, result) {
  let status = gen.next(result);
  if (!status.done) {
    const [command, param] = status.value;
    switch (command) {
      case "get:name":
        return processor(gen, "Tracy King");
      case "get:user":
        const [firstName, lastName] = param.split(" ");
        return processor(gen, { firstName, lastName });
    }
  }
}

processor(logic()); // Hey Tracy King

I don't see this often, but the generators are a way to go over a set of instructions (potentially asynchronous). In our case, the processor function iterates the generator by reading the commands, executing them, and passing the result back.