Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you avoid repetitions? [closed]

Tags:

java

Im using Java and am trying to give different tasks to things in different cases, but sometimes they do the same. This leads to some repetitions (actually long lines, not short method names), but is there an easy way to avoid these repetitions?

if(direction == Direction.UP) {
    doThingA(); // same thing as down
    doCustomThing1();
    doSameThing(); // all do this
    doCustomThing5();
} else if(direction == Direction.DOWN) {
    doThingA();
    doCustomThing2();
    doSameThing();
    doCustomThing6();
} else if(direction == Direction.RIGHT) {
    doThingB() // same thing as left
    doCustomThing3();
    doSameThing();
    doCustomThing7();
} else if(direction == Direction.LEFT) {
    doThingB()
    doCustomThing4();
    doSameThing();
    doCustomThing8();
}

Heres the real code, also as you can see, the custom things only differ slightly, but I have no idea how to simplify that:

if(direction == Direction.UP) {
    box.setAsBox(size.value/2, Constants.WORLD_HEIGHT/2);
    bodyDef.position.set(new Vector2(rand.nextFloat()*(Constants.WORLD_WIDTH-size.value)+size.value/2, -Constants.WORLD_HEIGHT*0.5f));
    body = gameWorld.world.createBody(bodyDef);
    body.setLinearVelocity(new Vector2(0f, 5f));
} else if(direction == Direction.DOWN) {
    box.setAsBox(size.value/2, Constants.WORLD_HEIGHT/2);
    bodyDef.position.set(new Vector2(rand.nextFloat()*(Constants.WORLD_WIDTH-size.value)+size.value/2, Constants.WORLD_HEIGHT*1.5f));
    body = gameWorld.world.createBody(bodyDef);
    body.setLinearVelocity(new Vector2(0f, -5f));
} else if(direction == Direction.RIGHT) {
    box.setAsBox(Constants.WORLD_WIDTH/2, size.value/2);
    bodyDef.position.set(new Vector2(-Constants.WORLD_WIDTH*0.5f, rand.nextFloat()*(Constants.WORLD_HEIGHT-size.value)+size.value/2));
    body = gameWorld.world.createBody(bodyDef);
    body.setLinearVelocity(new Vector2(5f, 0f));
} else if(direction == Direction.LEFT) {
    box.setAsBox(Constants.WORLD_WIDTH/2, size.value/2);
    bodyDef.position.set(new Vector2(Constants.WORLD_WIDTH*1.5f, rand.nextFloat()*(Constants.WORLD_HEIGHT-size.value)+size.value/2));
    body = gameWorld.world.createBody(bodyDef);
    body.setLinearVelocity(new Vector2(-5f, 0f));
}
like image 883
zebleckDAMM Avatar asked Dec 07 '25 10:12

zebleckDAMM


1 Answers

The moment I see an enums as a condition in a switch statement, or an if-else ladder, and the person writing the control statement owns the enum, I think it's a code smell.

Consider this alternative, instead of switching on the enum, why not use the same thing you do everywhere else? I suggest you give polymorphism a go here.

First, define your direction enum with some abstract methods if you have no default implementation that makes sense for the enums. This would be the same as getWidth() in the below example.

Secondly, add any non-abstract methods you might want that have sensible defaults. You can then override these methods just like you would in normal Java polymorphism. This would be the same as getHeight() in the below example.

This approach has a bunch of advantages.

  1. If you want to add more directions (let's say you went from 4 directions to 8, adding UP-LEFT, UP-RIGHT, DOWN-RIGHT, DOWN-LEFT) then you don't have to go through your entire code base and add the other if-else statements. You just add the implementation specific code for those new directions in your enum and you're done. It all just works.
  2. Adding default behavior is super easy, and you don't have to keep it in sync in multiple places in your codebase.
  3. The lines of code in your calling code gets reduced by the number of enums you have. If you had 10 enums, and had to write 10 calls for each enum, you'd have 121 lines of code (accounting for calls, and control statements), but after you start using polymorphism, you'll have 10 lines of code (no control statements, just method calls). This should reduce your cyclomatic complexity.
  4. You clearly encapsulate the functionality of the enum inside the enum itself. You have to be a little careful here, Enums can end up knowing about way too many parts of the system if you go nuts with this approach, but generally I find it's not an issue.

The Direction enum

public enum Direction {
    UP {
        public int getWidth() {
            return 50;
        }
        @Override
        public int getHeight() {
            return 100;
        }
    },
    DOWN {
        public int getWidth() {
            return 30;
        }
    };

    public abstract int getWidth();
    public int getHeight() {
        return 10;
    }
}

Now your calling code looks something like this.

box.setAsBox(direction.getWidth(), direction.getSize());
bodyDef.position.set(direction.getPositionVector());
body = gameWorld.world.createBody(direction.getBody());
body.setLinearVelocity(direction.getLinearVelocity());
like image 104
Jazzepi Avatar answered Dec 10 '25 03:12

Jazzepi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!