#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*/});
}