Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functionality according to assignment specifications #1

Merged
merged 2 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/app/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,9 @@ public static void main(String[] args) {
for (Subtask subtask : taskManager.getSubtasksOfEpic(epic1.getId())) {
System.out.println(subtask);
}
System.out.println("История задач:");
for (Task task : taskManager.getHistory()) {
System.out.println(task);
}
}
}
}
14 changes: 14 additions & 0 deletions src/manager/HistoryManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package manager;

import model.Task;

import java.util.List;

public interface HistoryManager {
void add(Task task);

void remove(int id);

List<Task> getHistory();
}

81 changes: 81 additions & 0 deletions src/manager/InMemoryHistoryManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package manager;

import model.Task;

import java.util.*;

public class InMemoryHistoryManager implements HistoryManager {
// Хранение задач по ID и узлов двусвязного списка
private final Map<Integer, Node> historyMap = new HashMap<>();
private Node head;
private Node tail;

@Override
public void add(Task task) {
if (task == null) return;

// Удаляем задачу из истории, если она уже существует
remove(task.getId());

// Добавляем задачу в конец списка
linkLast(task);
}

@Override
public void remove(int id) {
Node node = historyMap.remove(id);
if (node != null) {
removeNode(node);
}
}

@Override
public List<Task> getHistory() {
List<Task> history = new ArrayList<>();
Node current = head;
while (current != null) {
history.add(current.task);
current = current.next;
}
return history;
}

// Добавляет задачу в конец двусвязного списка
private void linkLast(Task task) {
Node newNode = new Node(task, tail, null);
if (tail != null) {
tail.next = newNode;
} else {
head = newNode;
}
tail = newNode;
historyMap.put(task.getId(), newNode);
}

// Удаляет узел из двусвязного списка
private void removeNode(Node node) {
if (node.prev != null) {
node.prev.next = node.next;
} else {
head = node.next;
}
if (node.next != null) {
node.next.prev = node.prev;
} else {
tail = node.prev;
}
}

// Вложенный класс для узла двусвязного списка
private static class Node {
Task task;
Node prev;
Node next;

Node(Task task, Node prev, Node next) {
this.task = task;
this.prev = prev;
this.next = next;
}
}
}
56 changes: 28 additions & 28 deletions src/manager/InMemoryTaskManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import model.Task;
import model.enums.StatusEnum;

import java.sql.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand All @@ -19,7 +18,7 @@ public class InMemoryTaskManager implements TaskManager {
private Map<Integer, EpicTask> epicData = new HashMap<>();
private Map<Integer, Subtask> subtaskData = new HashMap<>();

private final List<Task> history = new ArrayList<>();
private final HistoryManager historyManager = new InMemoryHistoryManager();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А давай все таки создадим класс Managers в котором будут методы

  • TaskManager getDefault()
  • HistoryManager getDefaultHistory()
    и все места создания обоих менеджеров через new заменим на вызовы соответствующих методов из списка выше.

Что нам это даст:

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


public Map<Integer, Task> getTaskData() {
return taskData;
Expand Down Expand Up @@ -131,15 +130,6 @@ public void updateSubtask(Subtask subtask) {
}
}

public void deleteTask(int id) {
Task task = taskData.remove(id);
if (task != null) {
System.out.println("Задача с id " + id + " удалена.");
} else {
System.out.println("Задача с id " + id + " не найдена.");
}
}

public void deleteEpic(int id) {
EpicTask epicTask = epicData.remove(id);
if (epicTask != null) {
Expand All @@ -154,18 +144,14 @@ public void deleteEpic(int id) {
}
}

public void deleteSubtask(int id) {
Subtask subtask = subtaskData.remove(id);
if (subtask != null) {
int epicId = subtask.getEpicId();
EpicTask epicTask = epicData.get(epicId);
if (epicTask != null) {
epicTask.getSubtasks().remove(subtask); // Преобразуем id в Integer и удаляем его из списка subtaskIds
updateEpicStatus(epicTask); // Обновляем статус эпика
}
System.out.println("Подзадача с id " + id + " удалена.");
@Override
public void deleteTask(int id) {
Task task = taskData.remove(id);
if (task != null) {
historyManager.remove(id); // Удаляем задачу из истории через HistoryManager
System.out.println("Задача с id " + id + " удалена.");
} else {
System.out.println("Подзадача с id " + id + " не найдена.");
System.out.println("Задача с id " + id + " не найдена.");
}
}

Expand All @@ -187,6 +173,7 @@ public List<Subtask> getSubtasksOfEpic(int epicId) {
}
}


@Override
public Task getAnyTask(int id) {
Task task = taskData.get(id);
Expand All @@ -198,20 +185,33 @@ public Task getAnyTask(int id) {
}

if (task != null) {
addToHistory(task); // Добавляем в историю
historyManager.add(task); // Добавляем в историю
}
return task;
}

private void addToHistory(Task task) {
if (history.size() == 10) { // Лимит истории - 10 задач
history.remove(0); // Удаляем самую старую задачу
@Override
public void deleteSubtask(int id) {
// Удаляем подзадачу из данных
Subtask subtask = subtaskData.remove(id);
if (subtask != null) {
// Если подзадача найдена, удаляем её из эпика
int epicId = subtask.getEpicId();
EpicTask epicTask = epicData.get(epicId);
if (epicTask != null) {
epicTask.getSubtasks().remove(subtask);
updateEpicStatus(epicTask); // Обновляем статус эпика
}
// Удаляем подзадачу из истории
historyManager.remove(id);
System.out.println("Подзадача с id " + id + " удалена.");
} else {
System.out.println("Подзадача с id " + id + " не найдена.");
}
history.add(task);
}

@Override
public List<Task> getHistory() {
return new ArrayList<>(history); // Возвращаем копию списка
return historyManager.getHistory(); // Возвращаем копию списка
}
}
1 change: 0 additions & 1 deletion src/manager/TaskManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import model.EpicTask;
import model.Subtask;

import java.util.ArrayList;
import java.util.List;

public interface TaskManager {
Expand Down
57 changes: 57 additions & 0 deletions test/manager/InMemoryHistoryManagerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package manager;

import model.*;
import model.enums.StatusEnum;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

import java.util.List;

class InMemoryHistoryManagerTest {

@Test
void shouldAddTaskToHistory() {
HistoryManager historyManager = new InMemoryHistoryManager();
Task task = new Task("Task 1", "Description 1", StatusEnum.NEW);
task.setId(1);

historyManager.add(task);

List<Task> history = historyManager.getHistory();
assertEquals(1, history.size(), "История должна содержать одну задачу.");
assertEquals(task, history.get(0), "Задача должна быть добавлена в историю.");
}

@Test
void shouldRemoveTaskFromHistory() {
HistoryManager historyManager = new InMemoryHistoryManager();
Task task1 = new Task("Task 1", "Description 1", StatusEnum.NEW);
Task task2 = new Task("Task 2", "Description 2", StatusEnum.NEW);
task1.setId(1);
task2.setId(2);

historyManager.add(task1);
historyManager.add(task2);
historyManager.remove(1);

List<Task> history = historyManager.getHistory();
assertEquals(1, history.size(), "История должна содержать одну задачу после удаления.");
assertEquals(task2, history.get(0), "Оставшаяся задача должна быть корректной.");
}

@Test
void shouldNotLimitHistorySize() {
HistoryManager historyManager = new InMemoryHistoryManager();

// Добавляем 15 задач
for (int i = 0; i < 15; i++) {
Task task = new Task("Task " + i, "Description " + i, StatusEnum.NEW);
task.setId(i);
historyManager.add(task);
}

List<Task> history = historyManager.getHistory();
assertEquals(15, history.size(), "История должна содержать все 15 задач без ограничения.");
}
}
20 changes: 11 additions & 9 deletions test/manager/InMemoryTaskManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,16 @@ void deleteSubtaskUpdatesEpic() {
}

@Test
void historySizeLimit() {
for (int i = 1; i <= 15; i++) {
Task task = new Task("Task " + i, "Description " + i, StatusEnum.NEW);
taskManager.addTask(task);
taskManager.getAnyTask(task.getId()); // Добавляем в историю
}

List<Task> history = taskManager.getHistory();
assertEquals(10, history.size(), "История не должна превышать 10 элементов.");
void shouldUpdateTaskFields() {
Task task = new Task("Old Name", "Old Description", StatusEnum.NEW);
taskManager.addTask(task);

task.setTitle("New Name");
task.setDescription("New Description");
taskManager.updateTask(task);

Task updatedTask = taskManager.getAnyTask(task.getId());
assertEquals("New Name", updatedTask.getTitle(), "Название задачи должно обновляться."); // Проверяем title
assertEquals("New Description", updatedTask.getDescription(), "Описание задачи должно обновляться."); // Проверяем description
}
}
Loading