Replacement for huge case statements

I am trying to improve a Java project that uses many large case statements. In cases where the case statement is used, it is used to process an event that has an attribute associated with it. For instance:

public void jumpOverWall(int wallID) { switch (wallID) { case 0: case 1213: case 2123: case 3123: case 4123: } } 

The numbers are not consecutive, and all require another action that needs to be performed - for example, "You cannot jump over this wall" or moving a character to a predetermined position. There are very few cases where the answer to this case follows a given pattern. I mean, switch statements do not follow a pattern that allows you to use code similar to:

 public void jumpOverWall(int wallID) { someArray[1213] = 10; someArray[3123] = 20; if (playerJumpingSkill > someArray[wallID]) { // Do something } else { sendPlayerMessage("You cannot do this!"); } } 

Therefore, I wonder how best to handle these "events." The whole idea of ​​the "event handler" style system is what appeals to me, but I'm stuck on how to implement it (or the best solution to the problem). Too many "events" (in my opinion) for each individual class.

Is there a method / project for hooking events? Will this be applicable / work. I would look at an easy connection method, for example:

 hookEvent(1213, new SomeInterface() { boolean eventOK() { // Do something return true; } } 

Then will these β€œhooks” be checked and called up?

+6
source share
3 answers

Why not have a separate method for each case? Thus, your code will become more readable.

 public void jumpOverWall(int wallID) { switch (wallID) { case 0: methodA(wallID); break; // you could of course have a more descriptive name here. case 1213: methodB(wallID); break; case 2123: methodC(wallID); break; case 3123: methodD(wallID); break; case 4123: methodE(wallID); break; } } 
+2
source

A team template might be the best option for you. Let's say you have an implementation of an object of the Interface command:

 public Interface Command { void processEvent(Event e); } 

Then you can have some hash of commands driven by event codes - much more readable. And you can even use the DI container (spring is the most popular, but there is also a picocontainer or google guice, and of course I skipped them) to create a command object - just register the corresponding objects with keys as event codes. This will save your code for the hash population.

And it doesn’t even have to be many clans - it can be just customized instances (depending on your use case) - today there are no class displays

+4
source

Since your wallIDs are really purely identifiers, and each of them controls jumpOverWall differently, you still need a different code. So I would really use different classes for your wallIDs . This way you can enable dynamic dispatch to distinguish between things. I do not understand why you think.

Too many "events" to have a separate class for each of them.

Since you need different code anyway, using classes will not blow your code.

Alternatively, you can use Enumerations with the default implementation of implementations :

 public enum WallID { 1213 { returnType jumpOverWall(Wall wall){ //... } }, 3213 { returnType jumpOverWall(Wall wall){ //... } }, 1332 { returnType jumpOverWall(Wall wall){ //... } }, //you can also use better names for your constants ;) abstract returnType jumpOverWall(Wall wall); } 

You can read in detail how this works, and why you should prefer enumerations over your int identifiers (since they really are purely identifiers) in Josh Bloch Effective Java, 2nd edition , paragraph 30 (use enumerations instead of int constants).

Update:

Using one of these two approaches instead of the int ID and the switch statement, you get several advantages:

  • more modular evaluation, therefore more readable and next SRP
  • more reusable, for example. when you want to inherit jumpOverWall behavior
  • you can associate additional data with each constant
  • you can provide additional methods for constants, again constant if you like
  • and what I find most important: security using the Java type system and dynamic dispatch.
+1
source

Source: https://habr.com/ru/post/909002/


All Articles