Java: making a singleton less verbose

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

I made a controller for playing as a single, as there should only be one. However, now I have Controller.getInstance()

ahead everywhere. How can I make this less verbose? Is Singleton even the way to go here?

I could put controller methods in default methods so I can just call click(x,y)

in implementations Player

, but that doesn't seem right.

Below I have a 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);
}
}

      

+3


source to share


4 answers


In the frontend, you can get the controller via 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 a 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);
  }

}

      

Thus, it is easier to change the decision about what it will be later.



Also, if you call a lot of controller methods in sequence, you might consider making it a fluent interface and renaming the getter just to controller

(I think it makes it faster), you would 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 further reduces verbosity ...

And, if the standard implementation that you provide in the interface for play

really needs to be overridden each time, you should consider abstracting it. The method giveUp

will still be available for class implementation.

+1


source


Just declare a local controller and call it 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);
    }
}

      

+2


source


Set it to a variable in the target context (s); even in a variable it is the same instance. Just another link to the same instance.

0


source


You can have a public Enum named SigletonEnum with one instance named INSTANCE . This is a singleton.

Since this is an enumeration, it is not required to create an instance. Then in the app you can call it

SingletonEnum.INSTANCE.doSomething();

      

0


source







All Articles