http://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html
The next step in emudev, with most compiled/systems languages at least, would be to create macros (such as OP_LD or OP_ADD) that generates static instructions at compilation. Another, cleanish method, in C is to generate a 256-length function pointer (void*) based static array and map those generated functions to that, to make the dispatch step simpler. Small trade off, performance-wise, but rarely matters for 8-bit CPU's (where you would usually use an opcode table over an instruction decoder).
Here's what such a code-generated instruction decoder looks like: https://github.com/floooh/chips/blob/master/chips/_z80_decod... (this is for a "real" Z80 with all undocumented opcodes, so it has a lot more cases to handle than the simple Gameboy Z80 variant).
You can see that in octal, 1xx are all moves while 2xx is all ALU ops.
My rust-based GB emulator uses a decoder based on those very docs, in fact. Though, modified slightly since the GB's CPU only supports the CB-extended range operations.