From 1ee2fc3d062068171b6c7372f7375acd7462b428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BE=D0=BB=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=93=D0=B5?= =?UTF-8?q?=D1=80=D0=BC=D0=B0=D0=BD?= Date: Wed, 26 Aug 2026 19:01:39 +0400 Subject: [PATCH] refactor: restructure application using MVP architecture --- app/src/main/java/ru/project/App.java | 41 ++++++----- app/src/main/java/ru/project/AppState.java | 18 ----- .../java/ru/project/CollectionController.java | 49 ------------- .../main/java/ru/project/DataCollection.java | 47 ------------- .../main/java/ru/project/model/AppState.java | 32 +++++++++ .../presenter/CollectionPresenter.java | 31 ++++++++ .../ru/project/presenter/MainPresenter.java | 70 +++++++++++++++++++ .../java/ru/project/ui/CollectionView.java | 10 --- .../ru/project/ui/CountOccurrencesMenu.java | 10 --- .../ru/project/ui/CreateCollectionMenu.java | 10 --- .../main/java/ru/project/ui/EmptyMenu.java | 23 ------ app/src/main/java/ru/project/ui/MainMenu.java | 34 --------- .../main/java/ru/project/ui/Navigator.java | 44 ------------ .../ru/project/ui/SaveCollectionMenu.java | 10 --- .../java/ru/project/ui/SearchElementMenu.java | 10 --- .../ru/project/ui/SortCollectionMenu.java | 10 --- .../java/ru/project/view/CollectionView.java | 47 +++++++++++++ .../main/java/ru/project/view/MainView.java | 62 ++++++++++++++++ 18 files changed, 266 insertions(+), 292 deletions(-) delete mode 100644 app/src/main/java/ru/project/AppState.java delete mode 100644 app/src/main/java/ru/project/CollectionController.java delete mode 100644 app/src/main/java/ru/project/DataCollection.java create mode 100644 app/src/main/java/ru/project/model/AppState.java create mode 100644 app/src/main/java/ru/project/presenter/CollectionPresenter.java create mode 100644 app/src/main/java/ru/project/presenter/MainPresenter.java delete mode 100644 app/src/main/java/ru/project/ui/CollectionView.java delete mode 100644 app/src/main/java/ru/project/ui/CountOccurrencesMenu.java delete mode 100644 app/src/main/java/ru/project/ui/CreateCollectionMenu.java delete mode 100644 app/src/main/java/ru/project/ui/EmptyMenu.java delete mode 100644 app/src/main/java/ru/project/ui/MainMenu.java delete mode 100644 app/src/main/java/ru/project/ui/Navigator.java delete mode 100644 app/src/main/java/ru/project/ui/SaveCollectionMenu.java delete mode 100644 app/src/main/java/ru/project/ui/SearchElementMenu.java delete mode 100644 app/src/main/java/ru/project/ui/SortCollectionMenu.java create mode 100644 app/src/main/java/ru/project/view/CollectionView.java create mode 100644 app/src/main/java/ru/project/view/MainView.java diff --git a/app/src/main/java/ru/project/App.java b/app/src/main/java/ru/project/App.java index 646773c..f7c48d9 100644 --- a/app/src/main/java/ru/project/App.java +++ b/app/src/main/java/ru/project/App.java @@ -2,39 +2,46 @@ package ru.project; import com.googlecode.lanterna.gui2.MultiWindowTextGUI; import com.googlecode.lanterna.screen.Screen; -import com.googlecode.lanterna.screen.TerminalScreen; import com.googlecode.lanterna.terminal.DefaultTerminalFactory; -import ru.project.ui.MainMenu; -import ru.project.ui.Navigator; +import ru.project.model.AppState; +import ru.project.presenter.MainPresenter; +import ru.project.view.MainView; public final class App { private App() {} - public static void main(String[] args) throws Exception { - DefaultTerminalFactory factory = new DefaultTerminalFactory(); - - Screen screen = new TerminalScreen(factory.createTerminal()); - - screen.startScreen(); + public static void main(String[] args) { + Screen screen = null; try { + DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory(); + + screen = terminalFactory.createScreen(); + screen.startScreen(); + MultiWindowTextGUI gui = new MultiWindowTextGUI(screen); - // Application state AppState state = new AppState(); + MainView view = new MainView(); - // Controllers - CollectionController collectionController = new CollectionController(state); + MainPresenter presenter = new MainPresenter(state, view, gui); - // Navigation - Navigator navigator = new Navigator(gui, collectionController); + presenter.start(); - // Application entry point - gui.addWindowAndWait(new MainMenu(navigator)); + } catch (Exception e) { + System.err.println("Произошла ошибка при выполнении программы:"); + e.printStackTrace(); } finally { - screen.stopScreen(); + if (screen != null) { + try { + screen.stopScreen(); + } catch (Exception e) { + System.err.println("Не удалось корректно завершить работу терминала:"); + e.printStackTrace(); + } + } } } } diff --git a/app/src/main/java/ru/project/AppState.java b/app/src/main/java/ru/project/AppState.java deleted file mode 100644 index 144f857..0000000 --- a/app/src/main/java/ru/project/AppState.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.project; - -public class AppState { - - private DataCollection collection; - - public DataCollection getCollection() { - return collection; - } - - public void setCollection(DataCollection collection) { - this.collection = collection; - } - - public boolean hasCollection() { - return collection != null; - } -} diff --git a/app/src/main/java/ru/project/CollectionController.java b/app/src/main/java/ru/project/CollectionController.java deleted file mode 100644 index 8cf3deb..0000000 --- a/app/src/main/java/ru/project/CollectionController.java +++ /dev/null @@ -1,49 +0,0 @@ -package ru.project; - -public class CollectionController { - - private final AppState state; - - public CollectionController(AppState state) { - this.state = state; - } - - public void createCollection() { - DataCollection collection = new DataCollection(); - - collection.add("Charlie"); - collection.add("Alice"); - collection.add("Bob"); - collection.add("Alice"); - - state.setCollection(collection); - } - - public DataCollection getCollection() { - return state.getCollection(); - } - - public boolean hasCollection() { - return state.hasCollection(); - } - - public void sortCollection() { - if (!state.hasCollection()) { - return; - } - - state.getCollection().sort(); - } - - public boolean contains(String element) { - return state.hasCollection() && state.getCollection().contains(element); - } - - public int countOccurrences(String element) { - if (!state.hasCollection()) { - return 0; - } - - return state.getCollection().count(element); - } -} diff --git a/app/src/main/java/ru/project/DataCollection.java b/app/src/main/java/ru/project/DataCollection.java deleted file mode 100644 index bd5553a..0000000 --- a/app/src/main/java/ru/project/DataCollection.java +++ /dev/null @@ -1,47 +0,0 @@ -package ru.project; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class DataCollection { - - private final List elements = new ArrayList<>(); - - public void add(String element) { - elements.add(element); - } - - public void sort() { - Collections.sort(elements); - } - - public boolean contains(String element) { - return elements.contains(element); - } - - public int count(String element) { - int count = 0; - - for (String current : elements) { - if (current.equals(element)) { - count++; - } - } - - return count; - } - - public List getElements() { - return Collections.unmodifiableList(elements); - } - - @Override - public String toString() { - if (elements.isEmpty()) { - return "Коллекция пуста"; - } - - return String.join(", ", elements); - } -} diff --git a/app/src/main/java/ru/project/model/AppState.java b/app/src/main/java/ru/project/model/AppState.java new file mode 100644 index 0000000..9b2a61e --- /dev/null +++ b/app/src/main/java/ru/project/model/AppState.java @@ -0,0 +1,32 @@ +package ru.project.model; + +import ru.project.collection.MyLinkedList; +import ru.project.collection.MyList; +import ru.project.student.Student; + +public class AppState { + + private MyList collection; + private String currentFilePath; + + public AppState() { + this.collection = new MyLinkedList<>(); + this.currentFilePath = null; + } + + public MyList getCollection() { + return collection; + } + + public void setCollection(MyList collection) { + this.collection = collection; + } + + public String getCurrentFilePath() { + return currentFilePath; + } + + public void setCurrentFilePath(String currentFilePath) { + this.currentFilePath = currentFilePath; + } +} diff --git a/app/src/main/java/ru/project/presenter/CollectionPresenter.java b/app/src/main/java/ru/project/presenter/CollectionPresenter.java new file mode 100644 index 0000000..f9c6606 --- /dev/null +++ b/app/src/main/java/ru/project/presenter/CollectionPresenter.java @@ -0,0 +1,31 @@ +package ru.project.presenter; + +import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import ru.project.collection.MyList; +import ru.project.model.AppState; +import ru.project.student.Student; +import ru.project.view.CollectionView; + +public class CollectionPresenter { + + private final AppState state; + private final CollectionView view; + private final WindowBasedTextGUI gui; + + public CollectionPresenter(AppState state, CollectionView view, WindowBasedTextGUI gui) { + this.state = state; + this.view = view; + this.gui = gui; + } + + public void start() { + MyList collection = state.getCollection(); + + if (collection == null || collection.isEmpty()) { + view.showEmptyMessage(gui); + return; + } + + view.showCollection(gui, collection); + } +} diff --git a/app/src/main/java/ru/project/presenter/MainPresenter.java b/app/src/main/java/ru/project/presenter/MainPresenter.java new file mode 100644 index 0000000..91b195b --- /dev/null +++ b/app/src/main/java/ru/project/presenter/MainPresenter.java @@ -0,0 +1,70 @@ +package ru.project.presenter; + +import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import com.googlecode.lanterna.gui2.dialogs.MessageDialog; +import com.googlecode.lanterna.gui2.dialogs.MessageDialogButton; +import ru.project.model.AppState; +import ru.project.view.CollectionView; +import ru.project.view.MainView; + +public class MainPresenter { + + private final AppState state; + private final MainView view; + private final WindowBasedTextGUI gui; + private final CollectionPresenter collectionPresenter; + + public MainPresenter(AppState state, MainView view, WindowBasedTextGUI gui) { + this.state = state; + this.view = view; + this.gui = gui; + this.collectionPresenter = new CollectionPresenter(state, new CollectionView(), gui); + } + + public void start() { + bindActions(); + view.show(gui); + } + + private void bindActions() { + view.setShowCollectionAction(this::showCollection); + view.setCreateCollectionAction(this::createCollection); + view.setSaveCollectionAction(this::saveCollection); + view.setSortCollectionAction(this::sortCollection); + view.setSearchCollectionAction(this::searchCollection); + view.setCountOccurrencesAction(this::countOccurrences); + view.setExitAction(this::exit); + } + + private void showCollection() { + collectionPresenter.start(); + } + + private void createCollection() { + showMessage("Меню создания коллекции."); + } + + private void saveCollection() { + showMessage("Меню сохранения коллекции."); + } + + private void sortCollection() { + showMessage("Меню сортировки коллекции."); + } + + private void searchCollection() { + showMessage("Меню поиска элемента."); + } + + private void countOccurrences() { + showMessage("Меню подсчёта количества вхождений."); + } + + private void exit() { + view.close(); + } + + private void showMessage(String message) { + MessageDialog.showMessageDialog(gui, "Информация", message, MessageDialogButton.OK); + } +} diff --git a/app/src/main/java/ru/project/ui/CollectionView.java b/app/src/main/java/ru/project/ui/CollectionView.java deleted file mode 100644 index ddad8cc..0000000 --- a/app/src/main/java/ru/project/ui/CollectionView.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.project.ui; - -import ru.project.CollectionController; - -public class CollectionView extends EmptyMenu { - - public CollectionView(CollectionController controller) { - super("Текущая коллекция"); - } -} diff --git a/app/src/main/java/ru/project/ui/CountOccurrencesMenu.java b/app/src/main/java/ru/project/ui/CountOccurrencesMenu.java deleted file mode 100644 index 5ef70e5..0000000 --- a/app/src/main/java/ru/project/ui/CountOccurrencesMenu.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.project.ui; - -import ru.project.CollectionController; - -public class CountOccurrencesMenu extends EmptyMenu { - - public CountOccurrencesMenu(CollectionController controller) { - super("Подсчёт количества вхождений"); - } -} diff --git a/app/src/main/java/ru/project/ui/CreateCollectionMenu.java b/app/src/main/java/ru/project/ui/CreateCollectionMenu.java deleted file mode 100644 index 69cfd2d..0000000 --- a/app/src/main/java/ru/project/ui/CreateCollectionMenu.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.project.ui; - -import ru.project.CollectionController; - -public class CreateCollectionMenu extends EmptyMenu { - - public CreateCollectionMenu(CollectionController controller) { - super("Создание новой коллекции"); - } -} diff --git a/app/src/main/java/ru/project/ui/EmptyMenu.java b/app/src/main/java/ru/project/ui/EmptyMenu.java deleted file mode 100644 index 0385780..0000000 --- a/app/src/main/java/ru/project/ui/EmptyMenu.java +++ /dev/null @@ -1,23 +0,0 @@ -package ru.project.ui; - -import com.googlecode.lanterna.gui2.BasicWindow; -import com.googlecode.lanterna.gui2.Button; -import com.googlecode.lanterna.gui2.Direction; -import com.googlecode.lanterna.gui2.Label; -import com.googlecode.lanterna.gui2.LinearLayout; -import com.googlecode.lanterna.gui2.Panel; - -public abstract class EmptyMenu extends BasicWindow { - - protected EmptyMenu(String title) { - super(title); - - Panel panel = new Panel(new LinearLayout(Direction.VERTICAL)); - - panel.addComponent(new Label("Раздел находится в разработке")); - - panel.addComponent(new Button("Назад", this::close)); - - setComponent(panel); - } -} diff --git a/app/src/main/java/ru/project/ui/MainMenu.java b/app/src/main/java/ru/project/ui/MainMenu.java deleted file mode 100644 index 361ce13..0000000 --- a/app/src/main/java/ru/project/ui/MainMenu.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.project.ui; - -import com.googlecode.lanterna.gui2.BasicWindow; -import com.googlecode.lanterna.gui2.Button; -import com.googlecode.lanterna.gui2.Direction; -import com.googlecode.lanterna.gui2.LinearLayout; -import com.googlecode.lanterna.gui2.Panel; - -public class MainMenu extends BasicWindow { - - public MainMenu(Navigator navigator) { - super("ГЛАВНОЕ МЕНЮ"); - - Panel panel = new Panel(new LinearLayout(Direction.VERTICAL)); - - panel.addComponent(new Button("Показать текущую коллекцию", navigator::showCollectionView)); - - panel.addComponent(new Button("Создать новую коллекцию", navigator::showCreateCollection)); - - panel.addComponent( - new Button("Сохранить текущую коллекцию в файл", navigator::showSaveCollection)); - - panel.addComponent(new Button("Сортировать текущую коллекцию", navigator::showSortCollection)); - - panel.addComponent(new Button("Найти элемент", navigator::showSearchElement)); - - panel.addComponent( - new Button("Подсчитать количество вхождений", navigator::showCountOccurrences)); - - panel.addComponent(new Button("Завершить выполнение программы", this::close)); - - setComponent(panel); - } -} diff --git a/app/src/main/java/ru/project/ui/Navigator.java b/app/src/main/java/ru/project/ui/Navigator.java deleted file mode 100644 index 873a1a4..0000000 --- a/app/src/main/java/ru/project/ui/Navigator.java +++ /dev/null @@ -1,44 +0,0 @@ -package ru.project.ui; - -import com.googlecode.lanterna.gui2.BasicWindow; -import com.googlecode.lanterna.gui2.WindowBasedTextGUI; -import ru.project.CollectionController; - -public class Navigator { - - private final WindowBasedTextGUI gui; - private final CollectionController collectionController; - - public Navigator(WindowBasedTextGUI gui, CollectionController collectionController) { - this.gui = gui; - this.collectionController = collectionController; - } - - public void show(BasicWindow window) { - gui.addWindowAndWait(window); - } - - public void showCollectionView() { - show(new CollectionView(collectionController)); - } - - public void showCreateCollection() { - show(new CreateCollectionMenu(collectionController)); - } - - public void showSaveCollection() { - show(new SaveCollectionMenu(collectionController)); - } - - public void showSortCollection() { - show(new SortCollectionMenu(collectionController)); - } - - public void showSearchElement() { - show(new SearchElementMenu(collectionController)); - } - - public void showCountOccurrences() { - show(new CountOccurrencesMenu(collectionController)); - } -} diff --git a/app/src/main/java/ru/project/ui/SaveCollectionMenu.java b/app/src/main/java/ru/project/ui/SaveCollectionMenu.java deleted file mode 100644 index 9f7d2e4..0000000 --- a/app/src/main/java/ru/project/ui/SaveCollectionMenu.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.project.ui; - -import ru.project.CollectionController; - -public class SaveCollectionMenu extends EmptyMenu { - - public SaveCollectionMenu(CollectionController controller) { - super("Сохранение текущей коллекции"); - } -} diff --git a/app/src/main/java/ru/project/ui/SearchElementMenu.java b/app/src/main/java/ru/project/ui/SearchElementMenu.java deleted file mode 100644 index b185219..0000000 --- a/app/src/main/java/ru/project/ui/SearchElementMenu.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.project.ui; - -import ru.project.CollectionController; - -public class SearchElementMenu extends EmptyMenu { - - public SearchElementMenu(CollectionController controller) { - super("Поиск элемента"); - } -} diff --git a/app/src/main/java/ru/project/ui/SortCollectionMenu.java b/app/src/main/java/ru/project/ui/SortCollectionMenu.java deleted file mode 100644 index 99bc1a8..0000000 --- a/app/src/main/java/ru/project/ui/SortCollectionMenu.java +++ /dev/null @@ -1,10 +0,0 @@ -package ru.project.ui; - -import ru.project.CollectionController; - -public class SortCollectionMenu extends EmptyMenu { - - public SortCollectionMenu(CollectionController controller) { - super("Сортировка текущей коллекции"); - } -} diff --git a/app/src/main/java/ru/project/view/CollectionView.java b/app/src/main/java/ru/project/view/CollectionView.java new file mode 100644 index 0000000..27d139e --- /dev/null +++ b/app/src/main/java/ru/project/view/CollectionView.java @@ -0,0 +1,47 @@ +package ru.project.view; + +import com.googlecode.lanterna.gui2.BasicWindow; +import com.googlecode.lanterna.gui2.Button; +import com.googlecode.lanterna.gui2.Label; +import com.googlecode.lanterna.gui2.LinearLayout; +import com.googlecode.lanterna.gui2.Panel; +import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import ru.project.collection.MyList; +import ru.project.student.Student; + +public class CollectionView { + + public void showCollection(WindowBasedTextGUI gui, MyList collection) { + BasicWindow window = new BasicWindow("Текущая коллекция"); + + Panel panel = new Panel(); + panel.setLayoutManager(new LinearLayout()); + + for (int i = 0; i < collection.size(); i++) { + Student student = collection.get(i); + + panel.addComponent(new Label((i + 1) + ". " + student)); + } + + panel.addComponent(new Button("Вернуться", window::close)); + + window.setComponent(panel); + + gui.addWindowAndWait(window); + } + + public void showEmptyMessage(WindowBasedTextGUI gui) { + BasicWindow window = new BasicWindow("Текущая коллекция"); + + Panel panel = new Panel(); + panel.setLayoutManager(new LinearLayout()); + + panel.addComponent(new Label("Текущая коллекция пуста.")); + + panel.addComponent(new Button("Вернуться", window::close)); + + window.setComponent(panel); + + gui.addWindowAndWait(window); + } +} diff --git a/app/src/main/java/ru/project/view/MainView.java b/app/src/main/java/ru/project/view/MainView.java new file mode 100644 index 0000000..632f2db --- /dev/null +++ b/app/src/main/java/ru/project/view/MainView.java @@ -0,0 +1,62 @@ +package ru.project.view; + +import com.googlecode.lanterna.gui2.ActionListBox; +import com.googlecode.lanterna.gui2.BasicWindow; +import com.googlecode.lanterna.gui2.LinearLayout; +import com.googlecode.lanterna.gui2.Panel; +import com.googlecode.lanterna.gui2.WindowBasedTextGUI; + +public class MainView { + + private final BasicWindow window; + private final ActionListBox menu; + + public MainView() { + window = new BasicWindow("Главное меню"); + + Panel panel = new Panel(); + panel.setLayoutManager(new LinearLayout()); + + menu = new ActionListBox(); + + panel.addComponent(menu); + + window.setComponent(panel); + } + + public void setShowCollectionAction(Runnable action) { + menu.addItem("Показать текущую коллекцию", action); + } + + public void setCreateCollectionAction(Runnable action) { + menu.addItem("Меню создания новой коллекции", action); + } + + public void setSaveCollectionAction(Runnable action) { + menu.addItem("Меню сохранения текущей коллекции в файл", action); + } + + public void setSortCollectionAction(Runnable action) { + menu.addItem("Меню сортировки текущей коллекции", action); + } + + public void setSearchCollectionAction(Runnable action) { + menu.addItem("Меню поиска элемента в текущей коллекции", action); + } + + public void setCountOccurrencesAction(Runnable action) { + menu.addItem("Меню подсчёта количества вхождений элемента", action); + } + + public void setExitAction(Runnable action) { + menu.addItem("Завершить выполнение программы", action); + } + + public void show(WindowBasedTextGUI gui) { + gui.addWindowAndWait(window); + } + + public void close() { + window.close(); + } +}