-
Notifications
You must be signed in to change notification settings - Fork 0
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
Спринт 9. #5
base: main
Are you sure you want to change the base?
Спринт 9. #5
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Добрый вечер, Алексей!
В целом хорошо, правда, есть ряд уточнений.
|
||
assertEquals(200, response.statusCode()); | ||
|
||
List<Task> parsed = gson.fromJson(response.body(), new TaskListTypeToken().getType()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Можно было получить нужный тип прямо здесь, чтобы не создавать пустой класс.
На усмотрение
List<Task> parsed = gson.fromJson(response.body(), new TypeToken<List<Task>>(){}.getType());
|
||
List<Task> parsed = gson.fromJson(response.body(), new TaskListTypeToken().getType()); | ||
|
||
assertTrue("Задачи не возвращаются", parsed.size() > 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Скорее вопрос... А что это за junit-библиотека, обычно же наоборот?
assertTrue(parsed.size() > 0, "Задачи не возвращаются");
|
||
import ru.alexgur.kanban.model.Task; | ||
|
||
public class TaskListTypeToken extends TypeToken<List<Task>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Насколько я увидел, эти классы, кроме двух (DurationAdapter и LocalTimeAdapter ), используются исключительно для тестирования. Лучше было бы перенести их в пакеты, связанные с тестированием.
Изменять код для тестов - это плохая практика. Тесты никак не должны влиять на дизайн классов программы. Правильный дизайн классов первичен, а тесты вторичны.
private static final String HISTORY_PATH = "/history"; | ||
private static final String PRIORITIZED_PATH = "/prioritized"; | ||
public static final String IP = "127.0.0.1"; // "localhost"; | ||
public static final int PORT = 8070; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
По ТЗ:
.--------------
Создайте класс HttpTaskServer — он будет слушать порт
import java.io.IOException; | ||
import java.net.InetSocketAddress; | ||
|
||
public class HttpTaskServer extends BaseHttpHandler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extends BaseHttpHandler {
Нет, не так. Зачем же он наследуется от обработчика, это разные вещи. По ТЗ:
.=================
Создайте класс HttpTaskServer — он будет слушать порт
.===============
На самом деле, Здесь всё проще, приблизительно так:
public class HttpTaskServer {
public static final int PORT = 8080;
private final HttpServer server;
private final TaskManager manager;
public HttpTaskServer(TaskManager manager) throws IOException {
this.manager = manager;
server = HttpServer.create(new InetSocketAddress("localhost", PORT), 0);
server.createContext("/tasks", new TasksHandler(manager));
server.createContext("/subtasks", new SubtasksHandler(manager));
server.createContext("/epics", new EpicsHandler(manager));
server.createContext("/history", new HistoryHandler(manager));
server.createContext("/prioritized", new PrioritizedHandler(manager));
}
public void start() {
System.out.println("Запустили TaskServer " + PORT);
server.start();
}
public void stop() {
server.stop(0);
System.out.println("Остановили сервер на порту " + PORT);
}
public static void main(String[] args) throws IOException {
TaskManager manager = Managers.getDefault();
HttpTaskServer taskServer = new HttpTaskServer(manager);
taskServer.start();
}
}
|
||
import java.nio.charset.StandardCharsets; | ||
|
||
public class HttpTaskManager extends HttpTaskServer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Сейчас получается, что вся бизнес-логика реализована в этом классе, что не совсем соответствует ООП. Хорошо было бы провести рефакторинг, в базовом классе (BaseHttpHandler) оставить обработчик и методы-заглушки, а в классах наследниках переопределять только эти методы (processGet, processPost….), если они нужны. Такое решение лучше соответствует принципам OOP
В результате должно получиться, что этот класс совсем не нужен.
Сейчас подробно распишу в базовом обработчике.
import com.google.gson.Gson; | ||
import com.google.gson.GsonBuilder; | ||
|
||
public class BaseHttpHandler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Здесь обработчик, методы-заглушки и служебные методы, приблизительно так:
public class BaseHandler implements HttpHandler {
......................
public void handle(HttpExchange exchange) throws IOException {
String method = exchange.getRequestMethod();
switch (method) {
case "GET":
processGet(exchange);
break;
case "POST":
processPost(exchange);
break;
case "DELETE":
processDelete(exchange);
break;
default:
writeToUser(exchange, "Данный метод не предусмотрен");
}
protected void processGet(....) {
sendMethodNotAllowed(...);
}
protected void processPost(....) {
sendMethodNotAllowed(...);
}
Далее в каждом из наследников мы будем переопределять только нужные для этого наследника методы processGet, processPost и т.д. и реализовывать в них нужную нам логику)
Почему возвращается статус 405 METHOD_NOT_ALLOWED можно посмотреть тут: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
httpExchange.getResponseBody().write(resp); | ||
httpExchange.close(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Для задач приблизительно так:
public class TasksHandler extends BaseHandler {
......................
public TasksHandler(........................
@Override
protected void processGet(HttpExchange exchange, String path) throws IOException {
.........................
@Override
protected void processPost(HttpExchange exchange) throws IOException {
...............
@Override
protected void processDelete(HttpExchange exchange, String path) throws IOException {
.......................
httpExchange.sendResponseHeaders(404, 0); | ||
httpExchange.close(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А для отсортированного по времени списка достаточно будет переопределить всего один метод:
public class PrioritizedHandler extends BaseHandler {
private final TaskService tasks;
public PrioritizedHandler(TaskService taskService) {
super(TaskGson.GSON);
this.tasks = taskService;
}
@Override
protected void processGet(HttpExchange exchange, String path) throws IOException {
..................
httpExchange.sendResponseHeaders(406, 0); | ||
httpExchange.close(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Аналогично определяются классы-наследники и для эпиков, подзадач, истории.
Сделать API, веб сервер, эндпойнты, тесты