Java — использование аннотаций для вызова разных функций?

#java #annotations

#java #аннотации

Вопрос:

В настоящее время я занимаюсь рефакторингом чат-бота, который я создал на Java, который подключается к нескольким разным веб-сайтам и должен выполнять действия по-разному в зависимости от платформы. Каждая платформа должна функционировать одинаково, но просто выполняется по-разному, в зависимости от API этого веб-сайта.

Для объяснения я буду использовать платформы Alpha и Beta (платформы, являющиеся платформами IRC / Websocket, а не операционными системами / устройствами.)

 public class MyMainClass {
  public static void main(String[] args) {
    sharedClass Alpha = new sharedClass( "Alpha" );
    sharedClass Beta  = new sharedClass( "Beta" );
  }
}
  

Подкласс

 /* To do so, I have created a shared class */
public class sharedClass {
  public String platformName = null;

  public sharedClass( String name ) {
    this.platformName = name;
  }

  /* Both platforms use many shared
   * functions, so I want to keep them
   * in the same class file, rather than
   * separating them.
   */
  public String sharedFunctionA() { return null; }
  public String sharedFunctionB() { return null; }
  /* ... */

  /* However, some functions that touch
   * on the APIs required picking out
   * different information.
   *
   * My goal is to get rid of these functions
   * so I can leave them as-is and not have
   * to add a new else to it every time I
   * add a new platform.
   */
  public String nitpickFunction() {

    /* Many similar functions exist,
     * where I am required to use more
     * than just two platforms.
     */
    if ( this.platformName.equals( /* Platform-Alpha */ ) ) {
      /* Do Stuff For Platform Alpha */

    } else if ( this.platformName.equals( /* Platform-Beta */ ) ) {
      /* Do Stuff For Platform Beta */

    } /* else if ( Platform-Gamma ) {
    } else if ( Platform-Delta ) {
    } else if ( Platform-Epsilon ) {
    } else if ( Platform-Zeta ) {
    } ...
    */

  }

  public String properFunction() {
    /* My hope (New To Creating Annotations)
     * is to do something similar to the following,
     * so that I can call what would have been inside
     * an if/else block, from the platforms respective
     * class file.
     */
    @DoPlatformNitpick
    myNitpickFunction();
    /*
     * Or just something like this
     */
    MyPlatform mySelectedFunction = new MyPlatform();
    mySelectedFunction.nitpick();
    /* However I believe that would require my
     * Alpha and Beta platforms to use the same
     * class type.
     */
  }

  /* Please ignore the possible NullPointerException,
   * this is just an example.
   */
}
  

Может кто-нибудь немного объяснить, как я мог бы это сделать, или возможно ли это вообще или нет?
Прокомментируйте, если мне нужно лучше объяснить. Я немного поискал, чтобы посмотреть, смогу ли я найти что-то подобное, но, возможно, что-то пропустил.

Комментарии:

1. Вероятно, вам следует расширить класс для каждой платформы, переопределив соответствующие методы.

2. Пожалуйста, проверьте, что interface и абстрактный класс есть в Java

Ответ №1:

Существует несколько способов сделать это, каждый из которых можно рассматривать как шаблон проектирования.

Абстрактный класс:

Для чего-то подобного я бы обычно использовал абстрактный класс вместо аннотации.

В абстрактном классе вы можете решить, для каких функций родительский класс предоставляет реализацию, а для каких дочерних классов. Вы можете сделать что-то формальное и создать новые вызываемые классы Alpha и Beta / или вы можете создавать анонимные классы. Ниже приведен пример анонимного класса.

 static abstract class Parent {

    public void sharedFunction() {

    }

    abstract void nitpick();

}

public static void main(String [] args) {

    Parent alpha = new Parent() {
        @Override
        void nitpick() {
            /*
            alpha specific code here
            */
        }
    };

}
  

Ниже приведен пример использования формального класса для бета-версии по сравнению с анонимным классом

     class Beta extends Parent {

    @Override
    void nitpick() {
        /*
        beta speicfic code goes here
        */
    }

}
  

Функциональный интерфейс:

Похоже на абстрактный класс, но с некоторыми ограничениями. Разделяемая функция должна использовать default предложение. И в интерфейсе есть один метод, который должен быть реализован.

     static interface Parent {

    default public void sharedFunction() {
    }

    abstract void nitpick();

}

public static void main(String[] args) {

    Parent alpha = () -> {/* alpha specific code goes here*/
    };

}
  

Передать реализацию в качестве входных данных:

При таком подходе реализация функции nitpick передается конструктору Parent класса.

     static class Parent {

    public void sharedFunction() {
    }

    final Runnable nitpick;

    public void nitPick() {
        nitpick.run();
    }

    public Parent(Runnable nitpick) {
        this.nitpick = nitpick;
    }

}

public static void main(String[] args) {

    Parent alpha = new Parent(() -> {/* alpha specific code goes here*/});

}