Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Помогите Рфакторинг кода новичка

Dodick

Активный участник
Пользователь
Баллы
61
Имя в Minecraft
Direktor
Java-bukkit Гуру прошу вас провести рефакторинг простого кода, простого плагина исполняющего команды /setspawn и /spawn. Джаву начал изучать совсем недавно и не знаю многих тонкостей, но решил написать свой первый плагин. Прошу поделиться мыслями и знаниями. Заранее спасибо! (использовалась java 21 для сервера майнкрафт 1.21)
Ссылка на скачивание исходника: https://dropmefiles.com/fECxE (14 дней)
 
Есть возможность использования других версий?
Нет, т.к плагин писался специально для самой последней. Хотя, если его скомпилировать на другой версии java, то возможно будет работать, т.к возможности java 21 не были применены
 
Код:
public static Main plugin;
@Override
public void onEnable() {
    plugin = this;
}
1. Так нельзя делать, независимо от того, работает или нет. Всем, кто советует так делать, я бы оборвал руки. Ознакомься с Dependency Injection через конструктор класса и пробрасывай необходимые объекты.
2. Ознакомиться с тем, что такое static поля и методы и зачем они нужны – во всех случаях использования в исходном коде они там не требуются. Более того, они показательно ломают парадигму ООП в случае реализации класса "CoordinatesConfigLoad".
3. В большинстве случаев поля класса должны быть приватными. Если к ним требуется доступ из других классов – реализовать геттер.
4. Ознакомиться с гайдлайнами Google по стилю оформления кода: https://google.github.io/styleguide/javaguide.html.
 
Код:
public static Main plugin;
@Override
public void onEnable() {
    plugin = this;
}
1. Так нельзя делать, независимо от того, работает или нет. Всем, кто советует так делать, я бы оборвал руки. Ознакомься с Dependency Injection через конструктор класса и пробрасывай необходимые объекты.
2. Ознакомиться с тем, что такое static поля и методы и зачем они нужны – во всех случаях использования в исходном коде они там не требуются. Более того, они показательно ломают парадигму ООП в случае реализации класса "CoordinatesConfigLoad".
3. В большинстве случаев поля класса должны быть приватными. Если к ним требуется доступ из других классов – реализовать геттер.
4. Ознакомиться с гайдлайнами Google по стилю оформления кода: https://google.github.io/styleguide/javaguide.html.

1. Полностью согласен, какой-то странный подход, но другого решения на тот момент не нашел для пробрасывания Plugin (в коде есть метод getPlugin()). Получается что в данном случае мы переменной присваиваем Главный класс и далее через нее обращаемся к нему? И решить это можно при помощи внедрения зависимостей?

2. Со статиком я более менее ознакомился. Пожалуй да, я в проекте с ним переборщил, но его все равно можно использовать в некоторых переменных, например для обращения к конфигу по полученному пути (если его не нужно будет менять из другого класса), т.к это удобнее всего.

3. С этим уже ознакомился

4. Буду просвещаться.

Если можно, можете пожалуйста реализовать пример для первого случая, не обязательно в этих исходниках, главное чтобы понятнее было, или ссылку на статью. Спасибо
 
в коде есть метод getPlugin()
Учитывая, что поле plugin публичное :)
И решить это можно при помощи внедрения зависимостей?
Код:
public class MyPlugin extends JavaPlugin {
  @Override
  public void onEnable() {
    Bukkit.getPluginManager().registerEvents(new MyListener(this), this);
  }

  // ...
}

public class MyListener implements Listener {

  private final MyPlugin plugin;

  public MyListener(MyPlugin plugin) {
    this.plugin = plugin;
  }

  // ...
}
 
Код:
public static Main plugin;
@Override
public void onEnable() {
    plugin = this;
}
1. Так нельзя делать, независимо от того, работает или нет. Всем, кто советует так делать, я бы оборвал руки. Ознакомься с Dependency Injection через конструктор класса и пробрасывай необходимые объекты.

Код:
import java.io.File;
//Типа главный класс
public final class Main extends JavaPlugin
{
    Test test = new Test();
    private void tesst()
    {
        test.Tester(this); //Передаем "себя" в другой метод другого класса
    }
}

//Второй класс
import org.bukkit.plugin.Plugin;

public class Test
{
    public void Tester(Plugin plugin) //тот самый метод
    {
        plugin.getConfig().get("bla-bla");
    }
}
 
Учитывая, что поле plugin публичное :)

Код:
public class MyPlugin extends JavaPlugin {
  @Override
  public void onEnable() {
    Bukkit.getPluginManager().registerEvents(new MyListener(this), this);
  }

  // ...
}

public class MyListener implements Listener {

  private final MyPlugin plugin;

  public MyListener(MyPlugin plugin) {
    this.plugin = plugin;
  }

  // ...
}

ой, не сразу видел ваш ответ) Спасибо за уделенное время:good:
 
Последнее редактирование:
И еще есть вопрос: стоит ли использовать одну переменную типа Player для всех классов или лучше в каждом классе создавать новую?
 
И еще есть вопрос: стоит ли использовать одну переменную типа Player для всех классов или лучше в каждом классе создавать новую?
А вот с этим я вообще прикола не понял, переменные везде свои, на уровне классов/в методах.
 
А вот с этим я вообще прикола не понял, переменные везде свои, на уровне классов/в методах.
По сути в плагине достаточно одной переменной типа Player, т.к плагин обрабатывает одного игрока за раз, разве нет? Не могу правильно изложить свою мысль, надеюсь вы поймете. Пример: игрок написал команду /spawn и дальше во всех классах и методах обрабатываем только одну переменную типа Player (отслеживаем события и т.д). Мне кажется, что это сравнимо с каким-нибудь фиксированным множителем, например число 2, и вместо того, чтобы каждый раз ее создавать (в классах) мы просто ссылаемся на нее (на оригинал).
 
По сути в плагине достаточно одной переменной типа Player, т.к плагин обрабатывает одного игрока за раз, разве нет?
Это весьма странный тезис, который укладывается только в случае, если среда однопоточная (и то еле-еле), и причина использовать единственную глобальную переменную под игрока. Ради чего? Переменная хранит ссылку на объект игрока, а не создает его в памяти, это ничего не стоит JVM. Каков бы ни был ответ, для меня нет ни одного стоящего оправдания. Нарушение инкапсуляции в перспективе.
 
Причина использовать единственную глобальную переменную под игрока. Ради чего? Переменная хранит ссылку на объект игрока, а не создает его в памяти, это ничего не стоит JVM.
Пожалуй я это и хотел услышать, боялся, что это может как-то повлиять на оптимизацию или память, если у меня будет много таких переменных. Про асинхронность знаю, начал изучать и экспериментировать
 
Почему тогда нужно использовать эту версию, если возможности не были применены
Так, а зачем мне писать на/для старых версиях, если есть возможность на новых? Тем более плагин написан был не для общего пользования и именно для поддержки сервера 1.21 (он использует последние версии java)

Для версий Minecraft 1.20.6 и выше требуется Java 21.
Для версий от 1.18.2 до 1.20.4 требуется Java 17.
Для версий 1.16.5 и 1.17.1 требуется Java 16.
Любые версии ниже могут использовать Java 8.
 

Поделиться этой страницей

Назад
Верх