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

Спринт 6 #2

Merged
merged 16 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
5f6d8e5
Сделать бесконечную историю со скоростью доступа О(1).
AlekseyGur Nov 23, 2024
b75ad15
Сделать бесконечную историю со скоростью доступа О(1).
AlekseyGur Nov 23, 2024
7f412e1
Спринт 6. Сделать бесконечную историю со скоростью доступа О(1)
AlekseyGur Nov 23, 2024
48d68c5
Merge branch 'sprint_6-solution' of https://github.com/AlekseyGur/jav…
AlekseyGur Nov 23, 2024
8948048
Спринт 6. Сделать бесконечную историю со скоростью доступа О(1)
AlekseyGur Nov 23, 2024
4b8653a
Изменить кодстайл
AlekseyGur Nov 23, 2024
ffd5151
Кодстайл
AlekseyGur Nov 24, 2024
995b588
Кодстайл
AlekseyGur Nov 24, 2024
d884f4d
Кодстайл
AlekseyGur Nov 24, 2024
434ec2f
Кодстайл
AlekseyGur Nov 24, 2024
c44a079
Кодстайл
AlekseyGur Nov 24, 2024
02e8742
Изменить таксономию, чтобы автотесты при PR запускались
AlekseyGur Nov 24, 2024
7e4877e
Изменение таксономии, чтобы пройти PR автотесты
AlekseyGur Nov 24, 2024
9481be0
Изменение таксономии, чтобы пройти PR автотесты
AlekseyGur Nov 24, 2024
fb53910
Изменение таксономии, чтобы пройти PR автотесты
AlekseyGur Nov 24, 2024
839d192
Разбить файл тестов на файлы и папки, сделать Node
AlekseyGur Nov 27, 2024
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
146 changes: 143 additions & 3 deletions src/Main.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,148 @@
import ru.alexgur.kanban.tests.Tests;
import java.util.List;
import ru.alexgur.kanban.model.Epic;
import ru.alexgur.kanban.model.SubTask;
import ru.alexgur.kanban.model.Task;
import ru.alexgur.kanban.service.HistoryManager;
import ru.alexgur.kanban.service.Managers;
import ru.alexgur.kanban.service.Status;
import ru.alexgur.kanban.service.TaskManager;

public class Main {
public static void main(String[] args) {
Tests tests = new Tests();
tests.startManual();
Main ex = new Main();
ex.startManual();
}

public void startManual() {

TaskManager tm = Managers.getDefault();
HistoryManager hm = Managers.getDefaultHistory();
tm.setHistoryManager(hm);

// Создаём первую эпик задачу
SubTask subTask1 = new SubTask();
SubTask subTask2 = new SubTask();
SubTask subTask3 = new SubTask();
Epic epic1 = new Epic();

tm.addSubTask(subTask1);
tm.addSubTask(subTask2);
tm.addSubTask(subTask3);
tm.addEpic(epic1);

subTask1.setName("Первая подзадача").setText("Собрать коробки");
subTask1.setName("Втоаря подзадача").setText("Упаковать кошку");
subTask1.setName("Третья подзадача").setText("Сказать слова прощания");
epic1.setName("Переезд").setText("Перва эпик задача");

epic1.setSubTasksIds(List.of(subTask1.id, subTask2.id, subTask3.id));
subTask1.setEpicId(epic1.id);
subTask2.setEpicId(epic1.id);
subTask3.setEpicId(epic1.id);

// Создаём вторую эпик задачу
SubTask subTask4 = new SubTask();
Epic epic2 = new Epic();

tm.addSubTask(subTask4);
tm.addEpic(epic2);

subTask4.setName("Небольшое дело").setText("закончить программу");
epic2.setName("Вторая эпик задача").setText("Описание задачи");

epic2.setSubTasksIds(List.of(subTask4.id));
subTask4.setEpicId(epic2.id);

// Изменяем статусы созданных объектов и печатаем их
SubTask st1 = tm.getEpicSubTasks(epic1.id).get(0);
SubTask st2 = tm.getEpicSubTasks(epic1.id).get(1);
SubTask st3 = tm.getEpicSubTasks(epic2.id).get(0);
st1.setStatus(Status.IN_PROGRESS);
st2.setStatus(Status.DONE);
st3.setStatus(Status.DONE);
tm.updateSubTask(st1);
tm.updateSubTask(st2);
tm.updateSubTask(st3);

// Печатаем всё
printAllTasks(tm);

// Теты
System.out.println("Автотесты:");

// Проверяем - статус подзадачи изменился
Status status;
status = tm.getSubTask(st1.id).getStatus();
if (status == Status.IN_PROGRESS)
System.out.println("✅ - Статус подзадачи успешно изменился на: " + status);
else
System.out.println("❌ - Ошибка проверки изменения статуса - 1");

status = tm.getSubTask(st2.id).getStatus();
if (status == Status.DONE)
System.out.println("✅ - Статус подзадачи успешно изменился на: " + status);
else
System.out.println("❌ - Ошибка проверки изменения статуса - 2");

status = tm.getSubTask(st3.id).getStatus();
if (status == Status.DONE)
System.out.println("✅ - Статус подзадачи успешно изменился на: " + status);
else
System.out.println("❌ - Ошибка проверки изменения статуса - 3");

// Проверяем - статус эпика 1 изменился
status = tm.getEpic(epic1.id).getStatus();
if (status == Status.IN_PROGRESS)
System.out.println("✅ - Статус эпичной задачи 1 успешно изменился на: " + status);
else
System.out.println("❌ - Ошибка изменения статуса эпичной задачи");

// Проверяем - статус эпика 2 изменился
status = tm.getEpic(epic2.id).getStatus();
if (status == Status.DONE)
System.out.println("✅ - Статус эпичной задачи 2 успешно изменился на: " + status);
else
System.out.println("❌ - Ошибка изменения статуса эпичной задачи");

// Удалим одну задачу из эпика
List<SubTask> st = tm.getEpicSubTasks(epic1.id);
int stSize = st.size();
tm.deleteSubTask(st.get(0).id);
if (tm.getEpicSubTasks(epic1.id).size() == --stSize)
System.out
.println("✅ - Успешно удалена задача из эпика. В эпике осталось " + stSize + " задач. Все верно.");
else
System.out.println("❌ - Ошибка удаления задачи из эпика");

// Удаляем один эпик
tm.deleteEpic(epic2.id);
if (tm.getEpic(epic2.id) == null)
System.out.println("✅ - Эпик задачи успешно удаляются");
else
System.out.println("❌ - Ошибка удаления эпик задачи");
}

private static void printAllTasks(TaskManager manager) {
System.out.println("Задачи:");
for (Task task : manager.getTasks()) {
System.out.println(task);
}
System.out.println("Эпики:");
for (Task epic : manager.getEpics()) {
System.out.println(epic);

for (Task task : manager.getEpicSubTasks(epic.id)) {
System.out.println("--> " + task);
}
}
System.out.println("Подзадачи:");
for (Task subtask : manager.getSubTasks()) {
System.out.println(subtask);
}

System.out.println("История:");
for (Task task : manager.getHistoryManager().getHistory()) {
System.out.println(task);
}
}
}
2 changes: 1 addition & 1 deletion src/ru/alexgur/kanban/service/HistoryManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public interface HistoryManager {

void add(Task task);

void clear();
void remove(int id);

List<Task> getHistory();

Expand Down
123 changes: 111 additions & 12 deletions src/ru/alexgur/kanban/service/InMemoryHistoryManager.java
Original file line number Diff line number Diff line change
@@ -1,47 +1,146 @@
package ru.alexgur.kanban.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import ru.alexgur.kanban.model.Task;

public class InMemoryHistoryManager implements HistoryManager {
private Node head;
private Node tail;
private HashMap<Integer, Node> history = new HashMap<>();

public static final int HISTORY_MAX_SIZE = 10;

private ArrayList<Task> history = new ArrayList<>();

@Override
public void clear() {
clearImpl();
}

@Override
public void remove(int id) {
removeImpl(id);
}

@Override
public void add(Task task) {
addImpl(task);
}

@Override
public List<Task> getHistory() {
return getHistoryImpl();
List<Task> listTasks = new ArrayList<>();
for (Node node : getTasks()) {

Choose a reason for hiding this comment

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

Формирование общего списка задач в истории можно было бы упростить.
На усмотрение.

public ArrayList<Task> getHistory() {
	ArrayList<Task> tasks = new ArrayList<>();

	Node node = first;
	while (node != null) {
		tasks.add(node.task);
		node = node.next;
	}
	return tasks;
}

Copy link
Owner Author

Choose a reason for hiding this comment

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

Пока оставил, чтобы не было дубликования кода с приватным методом getTasks.

Choose a reason for hiding this comment

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

Так в этом случае приватный метод вообще будет не нужен.

listTasks.add(node.getTask());
}
return listTasks;
}

private Node linkLast(Task task) {
final Node oldtail = tail;
final Node newNode = new Node(oldtail, task, null);
tail = newNode;
if (oldtail == null) {
head = newNode;
} else {
oldtail.setNext(newNode);
}
return newNode;
}

private ArrayList<Node> getTasks() {
ArrayList<Node> nodes = new ArrayList<>();
Node currentNode = head;
while (currentNode != null) {
nodes.add(currentNode);
currentNode = currentNode.getNext();
}
Collections.reverse(nodes);
return nodes;
}

private void addImpl(Task task) {
if (task != null) {
history.add(task);
if (history.size() > HISTORY_MAX_SIZE) {
history.remove(0);
if (history.containsKey(task.getId())) {
Node node = history.remove(task.getId());
removeNode(node);
}
Node node = linkLast(task);
history.put(task.getId(), node);
}
}

private List<Task> getHistoryImpl() {
List<Task> res = history;
return List.copyOf(res);
private void removeNode(Node node) {
Node prev = node.getPrev();
Node next = node.getNext();

if (prev != null && next != null) {
// Удаляетяся элемент в середине списка
next.setPrev(prev);
prev.setNext(next);
} else if (prev == null && next != null) {
// Удаляетяся первый элемент
head = next;
next.setPrev(null);
} else if (prev != null && next == null) {
// Удаляетяся последний элемент
tail = prev;
prev.setNext(null);
}

history.remove(node.getTask().getId());
}

private void removeImpl(int id) {
history.remove(id);
}

private void clearImpl() {
head = null;
tail = null;
history.clear();
}

private class Node {
private Task task;
private Node next;
private Node prev;

public Node(Node prev, Task task, Node next) {
this.task = task;
this.next = next;
this.prev = prev;
}

@Override
public int hashCode() {
return task.hashCode();
}

@Override
public boolean equals(Object obj) {
Node other = (Node) obj;
return task.equals(other.task);
}

public Task getTask() {
return task;
}

public Node getNext() {
return next;
}

public void setNext(Node next) {
this.next = next;
}

public Node getPrev() {
return prev;
}

public void setPrev(Node prev) {
this.prev = prev;
}
}

}
15 changes: 7 additions & 8 deletions src/ru/alexgur/kanban/service/InMemoryTaskManager.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package ru.alexgur.kanban.service;

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

import ru.alexgur.kanban.model.Epic;
import ru.alexgur.kanban.model.SubTask;
import ru.alexgur.kanban.model.Task;

import java.util.ArrayList;
import java.util.HashMap;

public class InMemoryTaskManager implements TaskManager {

// Ключ хеша совпадает с Task.id, используется для быстрого поиска
private HashMap<Integer, Task> tasks = new HashMap<>();
private HashMap<Integer, SubTask> subTasks = new HashMap<>();
private HashMap<Integer, Epic> epics = new HashMap<>();
Expand Down Expand Up @@ -169,12 +168,12 @@ private void updateEpicStatus(Epic epic, List<SubTask> subTasks) {

Status newStatus;
if (isNew) {
// все подзадачи имеют статус NEW или их нет
newStatus = Status.NEW;
} // все подзадачи имеют статус NEW или их нет
else if (isDone) {
} else if (isDone) {
// все подзадачи имеют DONE
newStatus = Status.DONE;
} // все подзадачи имеют DONE
else {
} else {
newStatus = Status.IN_PROGRESS;
}

Expand Down
Loading