12 KiB
12 KiB
План рефакторинга LoChat
Цель
Убрать legacy код, перевести всё на новую архитектуру (SOLID + DI через ServiceRegistry)
Текущая структура
✅ Новая архитектура (уже готово)
src/main/java/com/loki/lochat/
├── api/ # Интерфейсы сервисов
│ ├── service/
│ │ ├── ChatService.java
│ │ ├── MuteService.java
│ │ ├── AntiSpamService.java
│ │ ├── CooldownService.java
│ │ ├── MessageService.java
│ │ └── PlayerDataService.java
│ └── filter/
│ └── MessageFilter.java
├── core/ # Реализации
│ ├── service/
│ │ ├── ChatServiceImpl.java
│ │ ├── MuteServiceImpl.java
│ │ ├── AntiSpamServiceImpl.java
│ │ ├── CooldownServiceImpl.java
│ │ ├── MessageServiceImpl.java
│ │ └── PlayerDataServiceImpl.java
│ ├── filter/
│ │ ├── MuteFilter.java
│ │ ├── CooldownFilter.java
│ │ ├── SpamFilter.java
│ │ └── WordFilter.java
│ └── registry/
│ └── ServiceRegistry.java
└── listener/ # Новые слушатели
├── ChatEventListener.java (35 строк)
└── PlayerEventListener.java (23 строки)
❌ Legacy код (нужно удалить/переписать)
src/main/java/com/loki/lochat/
├── managers/ # Старые менеджеры
│ ├── MuteManager.java (409 строк) ❌
│ ├── ChatManager.java (131 строк) ❌
│ ├── AntiSpamManager.java ❌
│ ├── CooldownManager.java ❌
│ ├── PMManager.java ❌
│ ├── IgnoreManager.java ❌
│ ├── SpyManager.java ❌
│ ├── MentionManager.java (123 строки) ❌
│ ├── AutoMessageManager.java (159 строк) ⚠️
│ └── CustomCommandManager.java (269 строк) ⚠️
└── listeners/
└── ChatListener.java (185 строк) ❌
Этап 1: Анализ зависимостей
1.1 Проверить что использует legacy менеджеры
# Найти все вызовы getMuteManager(), getChatManager() и т.д.
grep -r "getMuteManager\|getChatManager\|getAntiSpamManager" src/main/java/com/loki/lochat/commands/
1.2 Составить список команд для миграции
- ChatEventListener - уже использует ServiceRegistry
- MuteCommand - использует MuteManager
- UnmuteCommand - использует MuteManager
- MuteListCommand - использует MuteManager
- MuteHistoryCommand - использует MuteManager
- MuteBlameCommand - использует MuteManager
- GlobalChatCommand - использует ChatManager
- LocalChatCommand - использует ChatManager
- MsgCommand - использует PMManager, IgnoreManager
- ReplyCommand - использует PMManager, IgnoreManager
- IgnoreCommand - использует IgnoreManager
- UnignoreCommand - использует IgnoreManager
- ChatSpyCommand - использует SpyManager
Этап 2: Создание новых сервисов
2.1 PMService (личные сообщения)
// api/service/PMService.java
public interface PMService {
void sendPrivateMessage(Player sender, Player receiver, String message);
Optional<UUID> getLastConversation(UUID player);
void setLastConversation(UUID player, UUID target);
}
// core/service/PMServiceImpl.java
public class PMServiceImpl implements PMService {
private final Map<UUID, UUID> conversations = new ConcurrentHashMap<>();
// ...
}
2.2 IgnoreService (игнорирование)
// api/service/IgnoreService.java
public interface IgnoreService {
boolean isIgnoring(UUID player, UUID target);
void addIgnore(UUID player, UUID target);
void removeIgnore(UUID player, UUID target);
int getIgnoredCount(UUID player);
}
// core/service/IgnoreServiceImpl.java
public class IgnoreServiceImpl implements IgnoreService {
private final Map<UUID, Set<UUID>> ignoreMap = new ConcurrentHashMap<>();
// ...
}
2.3 SpyService (шпионаж за чатом)
// api/service/SpyService.java
public interface SpyService {
boolean toggleSpy(UUID player);
boolean isSpying(UUID player);
void sendToSpies(Player sender, Object message, boolean isGlobal);
}
// core/service/SpyServiceImpl.java
public class SpyServiceImpl implements SpyService {
private final Set<UUID> spies = ConcurrentHashMap.newKeySet();
// ...
}
2.4 MentionService (упоминания)
// api/service/MentionService.java
public interface MentionService {
String processMentions(String message, Set<Player> mentioned);
void notifyMentioned(Set<Player> players);
}
// core/service/MentionServiceImpl.java
public class MentionServiceImpl implements MentionService {
// ...
}
Этап 3: Миграция команд
3.1 Mute команды
Приоритет: ВЫСОКИЙ (используют MuteManager 409 строк)
// Было:
public class MuteCommand {
private final LoChat plugin;
// plugin.getMuteManager().mute(...)
}
// Станет:
public class MuteCommand {
private final MuteService muteService;
public MuteCommand(LoChat plugin) {
this.muteService = plugin.getServiceRegistry().get(MuteService.class);
}
}
Файлы для миграции:
- MuteCommand.java
- UnmuteCommand.java
- MuteListCommand.java
- MuteHistoryCommand.java
- MuteBlameCommand.java
3.2 Chat команды
Приоритет: ВЫСОКИЙ
// Было:
plugin.getChatManager().sendGlobalMessage(...)
// Станет:
ChatService chatService = plugin.getServiceRegistry().get(ChatService.class);
chatService.sendGlobalMessage(...)
Файлы для миграции:
- GlobalChatCommand.java
- LocalChatCommand.java
3.3 PM команды
Приоритет: СРЕДНИЙ
Файлы для миграции:
- MsgCommand.java
- ReplyCommand.java
3.4 Ignore команды
Приоритет: СРЕДНИЙ
Файлы для миграции:
- IgnoreCommand.java
- UnignoreCommand.java
3.5 Spy команды
Приоритет: НИЗКИЙ
Файлы для миграции:
- ChatSpyCommand.java
Этап 4: Удаление legacy кода
4.1 Удалить старые менеджеры
После миграции всех команд:
rm src/main/java/com/loki/lochat/managers/MuteManager.java
rm src/main/java/com/loki/lochat/managers/ChatManager.java
rm src/main/java/com/loki/lochat/managers/AntiSpamManager.java
rm src/main/java/com/loki/lochat/managers/CooldownManager.java
rm src/main/java/com/loki/lochat/managers/PMManager.java
rm src/main/java/com/loki/lochat/managers/IgnoreManager.java
rm src/main/java/com/loki/lochat/managers/SpyManager.java
rm src/main/java/com/loki/lochat/managers/MentionManager.java
4.2 Удалить старый ChatListener
rm src/main/java/com/loki/lochat/listeners/ChatListener.java
4.3 Очистить LoChat.java
Удалить все legacy геттеры:
// Удалить:
public PMManager getPmManager() { return pmManager; }
public IgnoreManager getIgnoreManager() { return ignoreManager; }
public SpyManager getSpyManager() { return spyManager; }
public MuteManager getMuteManager() { return muteManager; }
public ChatManager getChatManager() { return chatManager; }
public AntiSpamManager getAntiSpamManager() { return antiSpamManager; }
public CooldownManager getCooldownManager() { return cooldownManager; }
public MentionManager getMentionManager() { return mentionManager; }
Этап 5: Оптимизация больших классов
5.1 ConfigManager (270 строк)
Проблема: Слишком много методов
Решение: Разбить на категории
// config/ChatConfig.java - настройки чата
// config/MuteConfig.java - настройки мутов
// config/SpamConfig.java - настройки антиспама
5.2 CustomCommandManager (269 строк)
Проблема: Много логики в одном классе
Решение: Вынести парсинг команд
// commands/custom/CustomCommandParser.java
// commands/custom/CustomCommandExecutor.java
5.3 GradientModule (249 строк)
Статус: Оставить как есть (это отдельный модуль)
5.4 AutoMessageManager (159 строк)
Статус: Оставить как есть (нормальный размер)
Этап 6: Тестирование
6.1 Написать тесты для новых сервисов
// test/java/com/loki/lochat/core/service/
├── PMServiceImplTest.java
├── IgnoreServiceImplTest.java
├── SpyServiceImplTest.java
└── MentionServiceImplTest.java
6.2 Интеграционные тесты
// test/java/com/loki/lochat/integration/
└── ChatFlowTest.java - тест полного флоу отправки сообщения
Этап 7: Финальная проверка
7.1 Проверить размеры классов
# Все классы должны быть < 150 строк (кроме модулей)
find src/main/java -name "*.java" -exec wc -l {} \; | sort -rn | head -20
7.2 Проверить архитектуру
- Все сервисы через интерфейсы
- Все зависимости через ServiceRegistry
- Нет прямых вызовов new Service()
- Все команды используют DI
7.3 Проверить производительность
- Нет утечек памяти
- Нет блокирующих операций в главном потоке
- Folia совместимость
Метрики успеха
До рефакторинга
- Главный класс: 166 строк
- Legacy менеджеры: 8 классов, ~1500 строк
- Старый ChatListener: 185 строк
- Дублирование кода: высокое
- Тестовое покрытие: 52 теста
После рефакторинга (цель)
- Главный класс: <100 строк
- Новые сервисы: 8 интерфейсов + 8 реализаций, ~800 строк
- Новые слушатели: 2 класса, ~60 строк
- Дублирование кода: минимальное
- Тестовое покрытие: >80 тестов
- Все классы: <150 строк
Порядок выполнения
- ✅ Создать новую архитектуру (api + core + registry)
- ✅ Мигрировать ChatEventListener
- ✅ Удалить эмодзи
- → Создать PMService, IgnoreService, SpyService, MentionService
- → Мигрировать все команды на новые сервисы
- → Удалить legacy менеджеры
- → Оптимизировать большие классы
- → Написать тесты
- → Финальная проверка
Примечания
- Миграция должна быть постепенной (по одной команде)
- После каждого шага - компиляция и тесты
- Сохранять обратную совместимость до полной миграции
- Документировать изменения в CHANGELOG.md