Kevin
Kevin

Reputation: 33

Java: Making singleton less verbose

To help me learn Java and programming concepts, I'm writing a bot that will solve the puzzles in the game PuzzleFreak .

I've made the controller for the game a singleton, since there should be only one. However, now I have Controller.getInstance() peppered everywhere. How can I make this less verbose? Is a Singleton even the way to go here?

I could wrap the controller methods in default methods so that I could just call click(x,y) in the Player implementations, but that feels wrong.

Below I have the Player interface and an example implementation.

Player.java:

public interface Player {

default void giveUp() {
    Controller.getInstance().click(new Rectangle(704, 545, 64, 18));
    Controller.getInstance().delay(0.1);
    Controller.getInstance().click(new Rectangle(704, 545, 64, 18));
}

default void play() {
    giveUp();
}
}

StartupPlayer.java:

public class StartupPlayer implements Player {

public void play(){
    Controller.getInstance().click(60, 278);
    Controller.getInstance().delay(0.5);
    Controller.getInstance().type("KevinBot");
    Controller.getInstance().delay(0.5);
    Controller.getInstance().click(400, 463);
}
}

Upvotes: 3

Views: 129

Answers (4)

Jordão
Jordão

Reputation: 56477

In the interface, you could get the controller through a getter:

public interface Player {

  default void giveUp() {
    Controller controller = getController();
    controller.click(new Rectangle(704, 545, 64, 18));
    controller.delay(0.1);
    controller.click(new Rectangle(704, 545, 64, 18));
  }

  default void play() {
    giveUp();
  }

  default Controller getController() {
    return Controller.getInstance();
  }

}

Then, the implementation class also uses the getter:

public class StartupPlayer implements Player {

  public void play(){
    Controller controller = getController();
    controller.click(60, 278);
    controller.delay(0.5);
    controller.type("KevinBot");
    controller.delay(0.5);
    controller.click(400, 463);
  }

}

This way, it's easier to change the decision that it's a singleton later on.

Also, if you'll be calling lots of controller methods in succession, you might consider making it a fluent interface, and renaming the getter simply to controller (I think it makes it more fluent as well), you'd have:

public interface Player {

  default void giveUp() {
    controller().
      click(new Rectangle(704, 545, 64, 18)).
      delay(0.1).
      click(new Rectangle(704, 545, 64, 18));
  }

  default void play() {
    giveUp();
  }

  default Controller controller() {
    return Controller.getInstance();
  }

}

public class StartupPlayer implements Player {

  public void play(){
    controller().
      click(60, 278).
      delay(0.5).
      type("KevinBot").
      delay(0.5).
      click(400, 463);
  }

}

This cuts down on the verbosity even further...

And, if the default implementation you provide in the interface for play is really meant to be overridden every time, you should consider keeping it abstract. The method giveUp would still be available for implementing classes to use.

Upvotes: 1

Rami Del Toro
Rami Del Toro

Reputation: 1150

You can have an public Enum called SigletonEnum with a single instance called INSTANCE. This is a singleton.

As this is an enum, it is not required to be instantiated.And then in the application you can call it as

SingletonEnum.INSTANCE.doSomething();

Upvotes: 0

Frank V
Frank V

Reputation: 25429

Set it to a variable in the target context(s) (class); even in a variable it's the same instance. Just a different reference to the same instance.

Upvotes: 0

Lawrence Aiello
Lawrence Aiello

Reputation: 4638

Just declare a local controller and call getInstance() once:

For example:

public class StartupPlayer implements Player {
    public void play(){
        Controller controller = Controller.getInstance()
        controller.click(60, 278);
        controller.delay(0.5);
        controller.type("KevinBot");
        controller.delay(0.5);
        controller.click(400, 463);
    }
}

Upvotes: 2

Related Questions